diff --git a/_docs/alfabank/payin_and_kyc/API_Key/api-key.md b/_docs/alfabank/payin_and_kyc/API_Key/api-key.md new file mode 100644 index 0000000..fa9c2ae --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/API_Key/api-key.md @@ -0,0 +1,61 @@ +Вот преобразованный контент страницы в формате Markdown. Я сохранил структуру, важные пометки (бета-тест, H2H) и все функциональные ссылки. + +--- + +# API Key + +**β-ТЕСТ** **H2H** + +**API Key** — ключ доступа для упрощённой авторизации запросов по H2H-интеграциям, который не требует аутентификации пользователей. Он выпускается один раз через интерфейс Портала разработчика и действует бессрочно, но будет автоматически отозван, если с момента последнего запроса прошло более 30 дней. + +### Сервисы, доступные с использованием `API Key` в H2H-интеграциях: + +* [Выписки по счетам юрлиц](/products/alfa-api/documentation/articles/transactions/transactions) (для методов, где `scope=transactions`) +* [Профиль организации](/products/alfa-api/documentation/articles/customer-info/customer-info) +* [Электронная подпись](/products/alfa-api/documentation/articles/signature/signature) + +Для настройки авторизации по `API Key` необходимо выпустить его на Портале разработчика и добавить его в свои рабочие инструменты. Как это сделать, описано [в статье Управление API Key](/products/alfa-api/documentation/articles/selfservice/articles/api-key/api-key). + +### Управление ключами доступа +Управлять ключами доступа можно также на Портале разработчика. Вы можете: + +* **Перевыпустить ключ** в случае потери данных, компрометации ключа или необходимости замены данных для него. +* **Отозвать ключ**, если больше не хотите использовать упрощённый способ авторизации. + +[**Как управлять API Key**](/products/alfa-api/documentation/articles/selfservice/articles/api-key/api-key) + +--- + +## Навигация по разделу +* ← [Экранирование](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening) +* → [Начало работы в песочнице](/products/alfa-api/documentation/articles/sandbox/articles/intro/intro) + +--- + +### Общая информация (Alfa API) +1. [Общая информация](/products/alfa-api/documentation/articles/specification/specification) +2. [Подключение к Alfa API](/products/alfa-api/documentation/articles/connection/connection) +3. [Портал разработчика](/products/alfa-api/documentation/articles/selfservice/selfservice) +4. [Alfa ID](/products/alfa-api/documentation/articles/alfa-id/alfa-id) +5. **API Key** (Текущая страница) +6. [Песочница](/products/alfa-api/documentation/articles/sandbox/sandbox) +7. [Java SDK](/products/alfa-api/documentation/articles/sdk/sdk) +8. [Обмен файлами](/products/alfa-api/documentation/articles/secure-file-transfer/secure-file-transfer) +9. [Транспортная подпись и шифрование](/products/alfa-api/documentation/articles/signature-encryption/signature-encryption) +10. [Вебхуки](/products/alfa-api/documentation/articles/webhooks/webhooks) + +### Продукты и сервисы +* [Выписки по счетам юрлиц](/products/alfa-api/documentation/articles/transactions/transactions) +* [Информация по счетам физлиц](/products/alfa-api/documentation/articles/accounts/accounts) +* [Эскроу-счета 214-ФЗ](/products/alfa-api/documentation/articles/escrow/escrow) +* [Профиль организации](/products/alfa-api/documentation/articles/customer-info/customer-info) +* [Платёжные поручения](/products/alfa-api/documentation/articles/payments/payments) +* [Самозанятые](/products/alfa-api/documentation/articles/selfemployed/selfemployed) +* [Система быстрых платежей (СБП)](/products/alfa-api/documentation/articles/sbp/sbp) +* [Кредиты](/products/alfa-api/documentation/articles/scoring/scoring) +* [Электронная подпись](/products/alfa-api/documentation/articles/signature/signature) +* [Карты](/products/alfa-api/documentation/articles/cards/cards) +* [Зарплатный проект](/products/alfa-api/documentation/articles/salary/salary) +* [Alfa Pay Business](/products/alfa-api/documentation/articles/invoices/invoices) +* [Факторинг](/products/alfa-api/documentation/articles/factoring/factoring) +* [Номинальные счета](/products/alfa-api/documentation/articles/nominal-accounts/nominal-accounts) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/access_token_refresh_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/access_token_refresh_POST.md new file mode 100644 index 0000000..49f7829 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/access_token_refresh_POST.md @@ -0,0 +1,114 @@ +# Обновление токена доступа + +**Тип интеграции:** B2B, B2C + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :-------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/token` | + +--- + +## Описание + +> **Внимание** +> Токен обновления действует 180 дней и не может быть использован более 2 раз. + +> **Внимание** +> Токен обновления может быть отозван в случае, если: +> +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +В результате запроса, помимо нового токена доступа, вы также получите новый токен обновления, а старый `refresh_token` станет недействительным. + +При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. В то время как `redirect_uri` экранировать не нужно. + +Если запрос отправляется через Postman с заголовком `"Content-Type": "application/x-www-form-urlencoded"` и `body` в формате `x-www-form-urlencoded` — нет необходимости экранировать специальные символы. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `refresh_token` | +| **refresh_token** | string | required | Токен обновления. Обновить `access_token` через `refresh_token` можно только 2 раза. В дальнейшем необходимо использовать новый `refresh_token` | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**HEADERS** + +- **Content-Type**: `application/json` +- **Cache-Control**: `no-store` +- **Pragma**: `no-cache` + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена (например, `Bearer`) | +| **expires_in** | integer | optional | Срок жизни токена в секундах | + +**Пример JSON-ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +--- + +### Ошибка (400 Bad Request) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Возможные значения: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Навигация + +- [← Получение профиля представителя пользователя](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/get-profile-info/v1/get-profile-info) +- [Как использовать ACF для H2H →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/how_to_use_ACF.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/how_to_use_ACF.md new file mode 100644 index 0000000..d63050c --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/how_to_use_ACF.md @@ -0,0 +1,50 @@ +# Как использовать ACF + +**Теги:** `B2B` `B2C` + +Вы можете использовать **Authorization Code Flow** в своих приложениях для получения доступа к защищённым ресурсам Alfa API. Доступ осуществляется с помощью `access_token`, который Вы получаете после аутентификации пользователя и подписания им согласия на передачу данных. + +Также с помощью полученного `access_token` Вы сможете: + +1. **Реализовать процесс бесшовной аутентификации** между партнёром и Банком. +2. **Получить доступ к операциям или документам других организаций** (при наличии от них согласия) для предоставления услуг B2B / B2C SaaS. Подходит для облачных бухгалтерий, маркетплейсов, CRM и других. + +`access_token`, полученный по **Authorization Code Flow**, даёт возможность переходить между банковскими приложениями и приложениями партнёра без дополнительной аутентификации. + +В рамках **Authorization Code Flow** доступны все сервисы, реализованные в Alfa API. + +--- + +### Шаги авторизации + +1. **Получение кода авторизации** +2. **Получение токена доступа** +3. **Получение информации о профиле представителя ЮЛ/ФЛ** +4. **Проверка подписи** +5. **Перенаправление авторизованного пользователя на ваш ресурс** + +--- + +### Согласия пользователей + +- **Срок жизни согласия:** 365 дней. +- **Продление:** После истечения срока необходимо заново пройти авторизацию. Для этого в параметре запроса на получение кода авторизации нужно передать параметр `prompt = consent`. +- **Проверка статуса:** Узнать дату окончания действия согласия можно с помощью метода [Данные по согласиям пользователей](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/client-consents/v1/client-consents). + +--- + +### Дополнительно + +При необходимости вы можете: + +- [Обновить токен](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/token-update/v1/token-update) +- [Отозвать токен](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token) + +--- + +**Навигация:** +← [Кнопка входа по Alfa ID](/products/alfa-api/documentation/articles/alfa-id/articles/button/button) | [Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/get-auth-code/v1/get-auth-code) → + +--- + +_Примечание: В данном документе используются относительные ссылки. Для перехода по ним используйте базовый адрес портала (developers.alfabank.ru)._ diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_a_user_representative_profile.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_a_user_representative_profile.md new file mode 100644 index 0000000..1236508 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_a_user_representative_profile.md @@ -0,0 +1,80 @@ +# Получение профиля представителя пользователя `B2B` `B2C` + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :---------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/oidc/userinfo` | +| **Пром** | `GET https://baas.alfabank.ru/oidc/userinfo` | + +--- + +## Описание + +Для идентификации пользователя выполняется запрос на получение информации о профиле представителя ЮЛ/ФЛ. + +- **Входящие параметры:** `access_token`. +- **Исходящие параметры:** данные пользователя, на передачу которых от пользователя есть разрешение. + +> Для каждого Партнёра API перечень допустимых клэймов настраивается индивидуально. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :-------------------- | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/jwt | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/userinfo' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/jwt' +``` + +--- + +## Параметры ответа + +### 200 OK + +**Headers:** + +- `Content-Type: application/jwt` (optional) + +**Пример ответа (JWT):** + +```text +eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJjdXMiOiJVQUFBQUEiLCJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJiaXJ0aGRhdGUiOiIyMDAwLTAyLTIwIiwicm9sZSI6IkFDQ09VTlRBTlQsIE1BTkFHRVIiLCJnZW5kZXIiOiJNQUxFIiwiaWRlbnRpdHlfZG9jdW1lbnRfbmFtZSI6ItCf0LDRgdC_0L7RgNGCINCz0YDQsNC20LTQsNC90LjQvdCwINCg0KQiLCJpZGVudGl0eV9kb2N1bWVudF9udW1iZXIiOjIyMjIyMiwiaXNzIjoiaHR0cHM6XC9cL2JhYXMuYWxmYWJhbmsucnUiLCJpbm4iOjc0MTUxMTExMjIyMiwiZWlvIjp0cnVlLCJnaXZlbl9uYW1lIjoi0KLQtdGB0YIiLCJtaWRkbGVfbmFtZSI6ItCi0LXRgdGC0L7QstC40YciLCJhY3VzIjoiWEFBQUFBIiwiaWRlbnRpdHlfZG9jdW1lbnRfc2VyaWVzIjoxMTExLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY2xjIjoiWEFBQUExIiwidXBkYXRlZF9hdCI6IjIwMjItMDEtMjAiLCJuYW1lIjoi0KLQtdGB0YLQvtCyINCi0LXRgdGCINCi0LXRgdGC0L7QstC40YciLCJwaG9uZV9udW1iZXIiOjc5MTkxMTEyMjMzLCJjbGMiOiJVQUFBQTEiLCJmYW1pbHlfbmFtZSI6ItCi0LXRgdGC0L7QsiIsImVtYWlsIjoiZW1haWxAZW1haWwucnUifQ.WVr5xkQSEGqpPXN3aIo0zHZLDL0vvtxEEQ83BrgJo7l0BjjALeGDRYENF2bL8j3n1pXRnduiBQcYNV6teBhESI8V_8kd7Kh7LTePkJWadPSvD__KskC69b4XZ-zN-IQ73NmAcBDStnnhSXGKL6xhdRy-TGiAoKPsRWiDVntsDlpCQNHAt3tJk8q_SQS4S1k6qju9eJ2GFkgmd6z8rR2vaBykaOF0K61ltksw6YgXhuek3OlYkqIAivyKYl59uio8zMpJk-YrPlmawwmvWPF0vKhaLj8Mvn4mVMsVSfuVVKP2ksHG0MAlWpO3Sh9GoKO4d6TQplJ4vgIIeNx-44npqw +``` + +### 400 Bad Request + +**Body:** + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Принимает значения: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Описание клэймов UserInfo + +| Name | Description | Scope | +| :-------------- | :-------------------------------------------------------------------- | :------------------ | +| **iss** | URL-адрес Alfa ID по протоколу https (https://id.alfabank.ru/oidc) | openid | +| **sub** | Уникальный идентификатор Alfa ID пользователя (до 255 символов ASCII) | openid | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | openid | +| **name** | Полное имя конечного пользователя в отображаемой форме | profile, name | +| **given_name** | Имя конечного пользователя | profile, givenname | +| **family_name** | Фамилия конечного пользователя | profile, familyname | +| **middle_name** | Отчество конечного пользователя | profile, middlename | +| **email** | Предпочтительный адрес электронной почты | email | +| **gender** | Пол конечного пользователя | profile, gender | +| **birthdate** | День рождения в формате `YYYY-MM-DD` | profile, birthdate | diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_access_token_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_access_token_POST.md new file mode 100644 index 0000000..0c2dc55 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_access_token_POST.md @@ -0,0 +1,155 @@ +# Получение токена доступа + +**Тип интеграции:** B2B, B2C +**Метод:** `POST` + +## Эндпоинты + +| Среда | URL | +| :------------ | :--------------------------------------- | +| **Песочница** | `https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `https://baas.alfabank.ru/oidc/token` | + +--- + +## Описание + +В результате выполнения запроса будет получено три токена: `access_token`, `refresh_token`, `id_token`. + +> **Внимание** +> +> - Токен доступа действует **1 час**. +> - Токен доступа может быть отозван в случае, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован; +> - срок жизни согласия пользователя истёк. + +### Особенности передачи параметров + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо **экранировать** специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** (body в формате `x-www-form-urlencoded`) — экранировать специальные символы не требуется. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :--------------- | :----- | :---- | :---------------------------------- | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/x-www-form-urlencoded` | + +### BODY (x-www-form-urlencoded) + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :--------------------------------------------------- | +| **grant_type** | string | Да | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | Да | Код авторизации | +| **client_id** | string | Да | Идентификатор партнёрского сервиса | +| **client_secret** | string | Да | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | Да | URI перенаправления | +| **code_verifier** | string | Нет | Код верификатор | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +## Параметры ответа + +### Ответ 200 (OK) + +**HEADERS** + +- `Content-Type`: `application/json` +- `Cache-Control`: `no-store` +- `Pragma`: `no-cache` + +**BODY** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | Да | Токен доступа | +| **refresh_token** | string | Да | Токен обновления | +| **token_type** | string | Да | Тип токена (обычно `Bearer`) | +| **expires_in** | integer | Нет | Срок жизни токена в секундах | +| **id_token** | string | Да | Идентификационный токен | + +**Пример JSON-ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +--- + +### Ответ 400 (Bad Request) + +| Атрибут | Тип | Обяз. | Описание | +| :-------------------- | :----- | :---- | :--------------------------------------- | +| **error** | string | Да | Код ошибки (например, `invalid_request`) | +| **error_description** | string | Нет | Описание ошибки | + +--- + +## Таблица возможных значений параметра error + +| Значение | Описание | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------ | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неподдерживаемый метод). | +| `invalid_grant` | Недействительный код авторизации, токен обновления или несоответствие URI перенаправления. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка. | + +--- + +## Описание клэймов (claims) + +### access_token + +| Значение | Описание | +| :----------------- | :----------------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix timestamp) | +| **iat** | Время выпуска токена (Unix timestamp) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +### id_token + +| Значение | Описание | Scope | +| :------------ | :--------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Строка для защиты от повторных атак | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_authorization_code_GET.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_authorization_code_GET.md new file mode 100644 index 0000000..4f7c390 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow/obtaining_an_authorization_code_GET.md @@ -0,0 +1,114 @@ +Вот преобразованный в Markdown контент вашего HTML-файла. Я сохранил структуру шагов, таблицы параметров, примеры кода и ссылки на изображения. + +--- + +# Получение кода авторизации + +**Теги:** `B2B` `B2C` + +Процесс получения кода авторизации в сценарии **Authorization Code Flow** состоит из нескольких шагов. + +--- + +### Краткий обзор шагов +1. Отобразите пользователю кнопку "Войти по Alfa ID". +2. Сформируйте ссылку для авторизации. +3. Переадресуйте пользователя для прохождения аутентификации. +4. Получите код авторизации в ответе от Alfa ID. +5. Alfa ID возвращает пользователя на Ваш ресурс по указанному `redirect_uri`. + +--- + +### Шаг 1. Кнопка «Войти по Alfa ID» +Пользователь переходит по встроенной кнопке на Вашем ресурсе. + +![windowAlfaId](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/picture3.png) + +--- + +### Шаг 2. Формирование ссылки + +#### Эндпоинты + +* **Песочница:** + `GET https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` +* **Пром:** + `GET https://id.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` + +> **Важно:** При формировании ссылки указывайте весь доступный `scope` через знак пробела или `%20`. Параметр `prompt=consent` используйте только если нужно, чтобы пользователь повторно подписал согласие. + +#### Параметры запроса (QUERY) + +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| `response_type` | string | Да | Тип ответа. Возможные значения: `code` | +| `client_id` | string | Да | Идентификатор партнёрского сервиса (выдается банком) | +| `redirect_uri` | string | Да | URI для перенаправления пользователя после успешной авторизации | +| `scope` | string | Да | Область применения (информирует, какие данные будут использованы) | +| `state` | string | Да | Параметр для защиты от CSRF. UUID, 36 символов. | +| `nonce` | string | Нет | Строка для связи сессии с ID-токеном и защиты от повторных атак | +| `code_challenge` | string | Нет | Код вызова | +| `code_challenge_method` | string | Нет | Метод преобразования: `plain` или `S256` | +| `prompt` | string | Нет | Параметр повторной аутентификации: `none`, `login`, `consent` | +| `max_age` | string | Нет | Максимальный период аутентификации | + +#### Пример запроса +```bash +curl -X GET https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode&scope=openid&state=abcdef +``` + +--- + +### Шаг 3. Аутентификация пользователя + +1. Пользователь проходит процедуру аутентификации. +![loginPassword](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/picture4.png) + +2. Пользователь выбирает организацию (для ЮЛ; для ФЛ шаг пропускается). +![organisationUL](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/picture6.png) + +3. Пользователь подписывает форму согласия. +![signForm](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/signForm.png) + +--- + +### Шаг 4. Получение кода авторизации + +Код авторизации получен, если пришел ответ **302 Found**. + +> **Внимание:** Код авторизации действует **2 минуты** и может быть использован только **1 раз**. + +#### Пример успешного ответа +```bash +https://wwww.partner.ru/code?code=8962c304-89b1-11ec-a8a3-0242ac120002&state=abcdef +-H 'Location: https://wwww.partner.ru/code?code=8962c304-89b1-11ec-a8a3-0242ac120002&state=abcdef' +-H 'Set-Cookie: ALFASESSIONID=f9e9532f-7b06-4023-83a2-f6cc77a7bfe4' +``` + +#### Параметры ответа (302 Found) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| `Location` | string | Содержит URI перенаправления вида: `redirect_uri?code={code}&state={state}` | +| `Set-Cookie` | string | Содержит идентификатор сессии | + +--- + +### Ошибки + +В случае неуспешного выполнения запроса в заголовке `Location` передаётся строка вида: `redirect_uri_error_page?error={error}`. + +#### Таблица возможных значений параметра error + +| Значение | Описание | +| :--- | :--- | +| `unsupported_response_type` | Сервер не поддерживает получение кода этим методом | +| `login_required` | Необходима аутентификация (возникает при `prompt=none`) | +| `invalid_scope` | Недопустимая или неизвестная область применения | +| `invalid_request` | Отсутствует обязательный параметр или неверный формат запроса | +| `consent_required` | Необходимо согласие пользователя (возникает при `prompt=none`) | +| `access_denied` | Владелец ресурса или сервер отклонил запрос | +| `invalid_operation_response` | Используйте только данные из спецификации ACF | +| `login_expired` | Пользователь не прошел аутентификацию за 15 минут или сделал logout | + +--- +**Далее:** [Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/get-access-token/v1/get-access-token) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/How_to_use_ACF_for_H2H.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/How_to_use_ACF_for_H2H.md new file mode 100644 index 0000000..43cace6 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/How_to_use_ACF_for_H2H.md @@ -0,0 +1,42 @@ +# Как использовать ACF для H2H + +**Тег:** `H2H` + +Вы можете использовать **Authorization Code Flow для H2H-интеграций** как канал взаимодействия ваших автоматизированных систем с Банком по операциям Вашей организации. + +С помощью `access_token`, полученного по **Authorization Code Flow для H2H-интеграций**, Вы сможете встроить банковские продукты в ERP-систему организации для выполнения запросов и операций только по своей организации. + +### Шаги авторизации + +1. **Формирование ссылки и редирект сотрудника** +2. **Получение кода авторизации** +3. **Получение токена доступа** + +### Дополнительно + +При необходимости вы можете [обновить](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/token-update/v1/token-update) токен или [отозвать](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token) его. + +--- + +#### Навигация по разделу: + +- ← [Обновление токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/token-update/v1/token-update) +- → [Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/get-auth-code) + +--- + +### Структура меню (Alfa ID): + +- [Что такое Alfa ID](/products/alfa-api/documentation/articles/alfa-id/articles/intro/intro) +- [Аутентификация](/products/alfa-api/documentation/articles/alfa-id/articles/authentication/authentication) +- [Кнопка входа по Alfa ID](/products/alfa-api/documentation/articles/alfa-id/articles/button/button) +- [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/acf) +- **Authorization Code Flow для H2H-интеграций** + - [Как использовать ACF для H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) (Текущая страница) + - [Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/get-auth-code) + - [Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-access-token/v1/get-access-token) `POST` + - [Обновление токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/token-update/v1/token-update) `POST` +- [Authorization Code Flow для холдингов](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/acf-holding) +- [Client Credentials Flow](/products/alfa-api/documentation/articles/alfa-id/articles/ccf/ccf) +- [Расширение сценариев](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/expansion) +- [Экранирование](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/geting_access_token_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/geting_access_token_POST.md new file mode 100644 index 0000000..c7d60fa --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/geting_access_token_POST.md @@ -0,0 +1,143 @@ +# Получение токена доступа `H2H` `POST` + +### Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :-------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/token` | + +--- + +### Описание + +В результате запроса будет получено три токена: `access_token`, `refresh_token`, `id_token`. + +> **Внимание** +> Токен доступа действует **1 час**. + +> **Внимание** +> Токен доступа может быть отозван в случае, если: +> +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. В то время как `redirect_uri` экранировать не нужно. + +Если запрос отправляется через Postman с заголовком `"Content-Type": "application/x-www-form-urlencoded"` и `body` в формате `x-www-form-urlencoded` — нет необходимости экранировать специальные символы. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | required | Код авторизации | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | required | URI перенаправления | +| **code_verifier** | string | optional | Код верификатор | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +### Параметры ответа + +#### Пример ответа 200 (OK) + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +#### Описание полей BODY (200 OK) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------ | :------------- | :--------------------------- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена | +| **expires_in** | integer | optional | Срок жизни токена в секундах | +| **id_token** | string | required | Идентификационный токен | + +--- + +### Ошибки (400 Bad Request) + +| Значение | Описание | +| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **invalid_request** | Отсутствует обязательный параметр, неподдерживаемое значение параметра (кроме grant_type), повторение параметра, несколько учётных данных или неправильный формат запроса | +| **invalid_client** | Ошибка аутентификации клиента (неизвестный клиент, отключенная аутентификация клиента или неподдерживаемый метод аутентификации) | +| **invalid_grant** | Недействительное разрешение авторизации (недействительный код авторизации, токен обновления или несоответствие URI перенаправления) | +| **unsupported_grant_type** | Тип разрешения на авторизацию (grant_type) не поддерживается сервером авторизации | +| **internal_error** | Произошла непредвиденная ошибка | + +--- + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :-------------------------------------------------------------------- | +| **iss** | URL-адрес Alfa ID по протоколу https (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя (до 255 символов ASCII) | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix timestamp UTC) | +| **iat** | Время выпуска токена (Unix timestamp UTC) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +### Описание клэймов ID_TOKEN + +| Значение | Описание | Scope | +| :------------ | :--------------------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Значение для связи сессии и защиты от повторных атак | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | + +--- + +**Навигация:** + +- [← Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/get-auth-code) +- [Обновление токена доступа →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/token-update/v1/token-update) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/obtaining_an_authorization_code.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/obtaining_an_authorization_code.md new file mode 100644 index 0000000..13538f9 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/obtaining_an_authorization_code.md @@ -0,0 +1,59 @@ +# Получение кода авторизации + +**Тип интеграции:** `H2H` + +### Шаг 1. Формирование ссылки + +Для получения кода авторизации необходимо сформировать GET-запрос. + +#### Эндпоинты: + +- **Песочница:** + `GET https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` +- **Пром:** + `GET https://id.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` + +#### Параметры: + +- `{client_id}` — идентификатор приложения Партнёра API, полученный после регистрации приложения на стороне Банка. +- `{redirect_uri}` — URI-адрес перенаправления для получения кода авторизации (можно использовать [http://localhost](http://localhost)). +- `{scope}` — области применения токена доступа, указывают, какие права должен содержать токен доступа (можно указать несколько через пробел), должны быть озвучены при регистрации приложения на стороне Банка. Например, для получения выписки необходимо указать `openid transactions`. +- `{state}` — любое строковое значение для защиты от CSRF, например `string12345`. + +**Пример итоговой ссылки:** +[https://id.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri=http://localhost&scope=openid transactions&state=string12345](https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=%7Bclient_id%7D&redirect_uri=http://localhost&scope=openid%20transactions&state=string12345) + +> **Внимание** +> Не забывайте заменить `{client_id}` на реальное значение, полученное после регистрации приложения на стороне Банка. + +--- + +### Шаг 2. Аутентификация + +1. В окне браузера отобразится страница аутентификации Alfa ID для ввода логина/пароля пользователя: + +![authAlfaID](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture8.png) + +2. После ввода логина/пароля пользователя отобразится страница второго фактора аутентификации для ввода otp-кода (sms, push): + +![otpCode](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture9.png) + +3. Необходимо ввести полученный на телефон otp-код (sms, push), и в адресной строке браузера отобразится код авторизации (`code`): + +![authorizationCode](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture11.jpg) + +--- + +### Шаг 3. Получение кода авторизации + +Полученное в браузере **значение кода авторизации** (параметр `code` в URL) необходимо скопировать и **обменять на [токен доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-access-token/v1/get-access-token)**. + +> **Внимание** +> Код авторизации по умолчанию действует **2 минуты** и может быть использован только **1 раз**. + +--- + +**Навигация:** + +- [← Как использовать ACF для H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) +- [Получение токена доступа →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-access-token/v1/get-access-token) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/refreshing_access_token_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/refreshing_access_token_POST.md new file mode 100644 index 0000000..3f1a9dd --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_H2H_Integrations/refreshing_access_token_POST.md @@ -0,0 +1,120 @@ +# Обновление токена доступа + +**Тип интеграции:** H2H (Host-to-Host) + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :-------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/token` | + +## Описание + +В результате запроса, помимо нового токена доступа, вы также получите новый токен обновления, а старый `refresh_token` станет недействительным. + +> [!IMPORTANT] +> **Внимание** +> +> - Токен обновления действует **180 дней** и не может быть использован более **2 раз**. +> - Токен обновления может быть отозван, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +### Особенности кодирования + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** с телом в формате `x-www-form-urlencoded` — экранировать символы вручную не требуется. +- Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `refresh_token` | +| **refresh_token** | string | required | Токен обновления. Обновить `access_token` можно только 2 раза. В дальнейшем нужно использовать новый `refresh_token`. | +| **client_id** | string | required | Идентификатор партнёрского сервиса. | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса. | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | required | Новый токен доступа. | +| **refresh_token** | string | required | Новый токен обновления. | +| **token_type** | string | required | Тип токена (обычно `Bearer`). | +| **expires_in** | integer | optional | Срок жизни токена в секундах. | + +**Пример ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +### Ошибка (400 Bad Request) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Например: `invalid_request` (неверные входные параметры). | +| **error_description** | string | optional | Текстовое описание ошибки. | + +--- + +## Дополнительная информация + +### Таблица возможных значений параметра error + +| Значение | Описание | +| :----------------------- | :---------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный ID или неверный secret). | +| `invalid_grant` | Недействительный токен обновления или несоответствие URI. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Внутренняя ошибка сервера. | + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :----------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc). | +| **sub** | Уникальный идентификатор пользователя. | +| **aud** | Идентификатор сервиса-партнёра (аудитория). | +| **exp** | Время окончания срока действия (Unix timestamp). | +| **iat** | Время выпуска токена. | +| **scope_claims** | Массив клэймов области применения. | +| **scope_services** | Массив операций области применения. | diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/access_token_refresh.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/access_token_refresh.md new file mode 100644 index 0000000..d7f034a --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/access_token_refresh.md @@ -0,0 +1,126 @@ +# Обновление токена доступа + +**Типы интеграции:** `B2B`, `H2H` + +## Эндпоинты + +| Окружение | Метод | URL | +| :------------ | :----- | :--------------------------------------- | +| **Песочница** | `POST` | `https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `POST` | `https://baas.alfabank.ru/oidc/token` | + +--- + +## Описание + +В результате запроса, помимо нового токена доступа, вы также получите новый токен обновления, а старый `refresh_token` станет недействительным. + +> **Внимание** +> +> - Токен обновления действует **180 дней** и не может быть использован **более 2 раз**. +> - При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. При этом `redirect_uri` экранировать не нужно. +> - Если запрос отправляется через **Postman** с телом в формате `x-www-form-urlencoded` — экранировать символы не нужно. +> - Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +### Токен обновления может быть отозван, если: + +- пользователь сменил пароль; +- пользователь превысил допустимое количество попыток ввода пароля; +- аккаунт пользователя был заблокирован. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :--------------- | :----- | :---- | :---------------------------------- | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/x-www-form-urlencoded` | + +### BODY (x-www-form-urlencoded) + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :-------------------------------------------------- | +| **grant_type** | string | Да | Тип гранта. Значение: `refresh_token` | +| **refresh_token** | string | Да | Токен обновления. Можно использовать только 2 раза. | +| **client_id** | string | Да | Идентификатор партнёрского сервиса | +| **client_secret** | string | Да | Секретный ключ партнёрского сервиса | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :---------------- | :------ | :----------------------------------- | +| **access_token** | string | Новый токен доступа | +| **refresh_token** | string | Новый токен обновления | +| **token_type** | string | Тип токена (обычно `Bearer`) | +| **expires_in** | integer | Срок жизни токена доступа в секундах | + +**Пример ответа 200:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +### Ошибка (400 Bad Request) + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :--------------------------------------- | +| **error** | string | Код ошибки (например, `invalid_request`) | +| **error_description** | string | Описание ошибки | + +--- + +## Справочные таблицы + +### Возможные значения параметра error + +| Значение | Описание | +| :----------------------- | :-------------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неверный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неверный `client_secret`). | +| `invalid_grant` | Недействительный `refresh_token`. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка на стороне сервера. | + +### Описание клэймов access_token + +| Клэйм | Описание | +| :----------------- | :----------------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix Timestamp) | +| **iat** | Время выпуска токена (Unix Timestamp) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +**Полезные ссылки:** + +- [Новости в Telegram](https://t.me/AlfaAPI) +- [Общая спецификация Alfa API](/products/alfa-api/documentation/articles/specification/specification) +- [Инструкция по подключению](/products/alfa-api/documentation/articles/connection/connection) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/getting_authorization_token.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/getting_authorization_token.md new file mode 100644 index 0000000..4d2b5af --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/getting_authorization_token.md @@ -0,0 +1,79 @@ +# Получение кода авторизации + +**Теги:** `B2B` `H2H` + +Процесс получения кода авторизации состоит из трех основных этапов: + +1. Сформируйте ссылку. +2. Переадресация дочерней компании для прохождения аутентификации. +3. Получение кода авторизации. + +--- + +## Шаг 1. Формирование ссылки + +### Эндпоинты + +- **Песочница:** + `GET https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` +- **Пром:** + `GET https://id.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}` + +### Описание + +Ссылка должна содержать обязательные параметры, указанные ниже в таблице. Также опционально могут быть использованы необязательные параметры. + +При формировании ссылки указывайте весь доступный `scope` через знак пробела или (`%20`). Дополнительный параметр `prompt=consent` использовать только в том случае, если необходимо, чтобы дочерняя компания подписала/переподписала новое согласие. + +Сформированную ссылку необходимо передать своим дочерним компаниям. + +### Параметры запроса (QUERY) + +| Атрибут | Тип | Обязательность | Описание | +| :------------------------ | :----- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------- | +| **response_type** | string | required | Тип ответа. Возможные значения: `code` | +| **client_id** | string | required | Идентификатор партнёрского сервиса (банк выдает партнёру API) | +| **redirect_uri** | string | required | URI перенаправления, необходимый для переадресации пользователя после успешной авторизации. На этот URI будет отправлен код авторизации. | +| **scope** | string | required | Область применения (партнёр API информирует, какой scope будет использован) | +| **state** | string | required | Параметр для предотвращения межсайтовой подделки запросов. Значение генерирует партнёр (UUID, 36 символов). | +| **nonce** | string | optional | Строковое значение для связи сессии клиента с ID-токеном и защиты от повторных атак. | +| **code_challenge** | string | optional | Код вызова. | +| **code_challenge_method** | string | optional | Метод преобразования кода верификатора. Значения: `plain`, `S256`. | +| **prompt** | string | optional | Параметр повторной аутентификации/согласия. Значения: `none`, `login`, `consent`. | +| **max_age** | string | optional | Максимальный период аутентификации. | + +### Пример ссылки + +```bash +https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode&scope=openid&state=abcdef +``` + +--- + +## Шаг 2. Аутентификация дочерней компании + +1. При переходе по ссылке дочерняя компания проходит процедуру аутентификации. + ![loginPassword](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-holding/articles/get-auth-code/v1/files/picture4.png) + +2. Выбирает необходимую организацию (при работе с несколькими юридическими лицами). + ![organisationUL](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-holding/articles/get-auth-code/v1/files/picture6.png) + +3. Далее проходит процедуру авторизации, **подписывая форму согласия**. + ![signForm](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-holding/articles/get-auth-code/v1/files/signForm.png) + +4. После прохождения авторизации в адресной строке браузера отобразится код авторизации (`code`). Дочерней компании необходимо скопировать этот код и передать головной компании. + ![authorizationCode](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-holding/articles/get-auth-code/v1/files/picture11.jpg) + +--- + +## Шаг 3. Получение кода авторизации + +Полученное от дочерней компании **значение кода авторизации** (code) необходимо скопировать и **обменять на [токен доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/get-access-token/v1/get-access-token)**. + +> **Внимание** +> Код авторизации по умолчанию действует **2 минуты** и может быть использован только **1 раз**. + +--- + +**Далее:** [Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/get-access-token/v1/get-access-token) +**Назад:** [Как использовать ACF для холдингов](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/how_to_use_acf_for_holdings.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/how_to_use_acf_for_holdings.md new file mode 100644 index 0000000..32a90df --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/how_to_use_acf_for_holdings.md @@ -0,0 +1,34 @@ +Вот преобразованный в Markdown контент страницы. Я очистил его от лишнего программного кода и навигационных элементов портала, оставив только суть документации, ссылки и структуру. + +--- + +# Как использовать ACF для холдингов + +**Теги:** `B2B` `H2H` + +Холдинги представляют собой интеграцию, которая включает в себя использования двух сценариев: партнёрские сервисы и прямая интеграция. + +С помощью одного `client_id` вы сможете выполнять запросы и операции по своей организации. Для этого необходимо получить `access_token` для прямой интеграции по [Authorization Code Flow для H2H-интеграций](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/acf-h2h). + +С помощью второго `client_id` вы сможете выполнять операции по своим дочерним компаниям. + +### Видео-инструкция +[Скачать или посмотреть видео](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-holding/articles/intro/files/acf-holding.mp4) + +### Шаги авторизации +1. **Формирование ссылки** +2. **Получение кода авторизации** +3. **Получение токена доступа** + +### Согласия пользователей +Срок жизни согласия пользователя – **365 дней**, после его истечения необходимо заново пройти авторизацию. Для этого в ссылке на получение кода авторизации необходимо передать параметр `prompt = consent`. + +Узнать дату окончания действия согласия можно с помощью метода [Данные по согласиям пользователей](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/client-consents/v1/client-consents). + +### Дополнительно +При необходимости вы можете [обновить](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/token-update/v1/token-update) токен или [отозвать](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token) его. + +--- + +**Навигация:** +← [Обновление токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/token-update/v1/token-update) | [Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/get-auth-code/v1/get-auth-code) → diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/obtaining_an_access_token.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/obtaining_an_access_token.md new file mode 100644 index 0000000..e96a530 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/Authorization_Code_Flow_for_Holding_Companies/obtaining_an_access_token.md @@ -0,0 +1,139 @@ +# Получение токена доступа + +### Эндпоинты + +| Окружение | Метод | URL | +| :------------ | :----- | :--------------------------------------- | +| **Песочница** | `POST` | `https://sandbox.alfabank.ru/oidc/token` | +| **Пром** | `POST` | `https://baas.alfabank.ru/oidc/token` | + +--- + +### Описание + +В результате запроса будет получено три токена: `access_token`, `refresh_token`, `id_token`. + +> **⚠️ Внимание** +> +> - Токен доступа действует **1 час**. +> - Токен доступа может быть отозван, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован; +> - срок жизни согласия пользователя истёк. + +#### Особенности кодирования: + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо **экранировать** специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** (формат `x-www-form-urlencoded`) — экранировать символы вручную не требуется. +- Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | required | Код авторизации | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | required | URI перенаправления | +| **code_verifier** | string | optional | Код верификатор | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +### Параметры ответа + +#### Пример ответа 200 (OK) + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +#### Описание полей ответа (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------ | :------------- | :--------------------------- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена (Bearer) | +| **expires_in** | integer | optional | Срок жизни токена в секундах | +| **id_token** | string | required | Идентификационный токен | + +--- + +### Таблица возможных значений параметра error (400 Bad Request) + +| Значение | Описание | +| :----------------------- | :---------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неверный метод). | +| `invalid_grant` | Недействительный код авторизации, токен обновления или несоответствие URI. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка. | + +--- + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :------------------------------------------------ | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор пользователя Alfa ID | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия (Unix timestamp) | +| **iat** | Время выпуска токена | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +### Описание клэймов ID_TOKEN + +| Значение | Описание | Scope | +| :------------ | :-------------------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска JWT | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Значение для связи сессии (если передавалось ранее) | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/alfa_id_login_button.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/alfa_id_login_button.md new file mode 100644 index 0000000..17d394d --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/alfa_id_login_button.md @@ -0,0 +1,48 @@ +# Кнопка входа по Alfa ID + +**Теги:** `B2B` `B2C` `H2H` + +Для того чтобы Ваши пользователи могли аутентифицироваться через Alfa ID, вы можете добавить кнопку **«Войти по Alfa ID»**, реализовав её в соответствии с требованиями, указанными на официальной странице руководства: + +🔗 [https://alfabank.ru/sme/guide-alfaid](https://alfabank.ru/sme/guide-alfaid) + +### Исходные файлы + +Вы можете импортировать макет кнопки для использования в своем дизайне из следующего файла: +📥 [Скачать button.fig](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/button/files/button.fig) + +--- + +## Общая информация об Alfa ID + +_(Данные из справочного раздела системы)_ + +**Alfa ID** — единая учётная запись пользователя ЮЛ (юридического лица) / ФЛ (физического лица), которая помогает пользователям входить на ваш сайт или в приложение, а также в продукты и сервисы Альфа-Банка. + +### Преимущества для пользователей + +- Простая и быстрая аутентификация на сайтах и в приложениях; +- Единый и безопасный аккаунт; +- Упрощение процесса покупки или подачи заявки; +- Безопасность персональных данных; +- Не нужно запоминать множество паролей. + +### Преимущества для партнёров + +- Простая и быстрая аутентификация, выше конверсия на вход; +- Быстрое получение актуальных данных пользователя от Банка; +- Автозаполнение форм и заявок; +- Проверка реальности пользователя; +- Индустриальные стандарты защиты данных и персональной информации; +- Отсутствие необходимости хранить персональные данные на своей стороне. + +### Рекомендуемые браузеры + +- **Яндекс Браузер:** версии 21 и выше; +- **Safari:** версии 16 и выше; +- **Google Chrome:** версии 117 и выше. + +--- + +**Навигация:** +← [Аутентификация](/products/alfa-api/documentation/articles/alfa-id/articles/authentication/authentication) | [Как использовать ACF](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) → diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/authentication.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/authentication.md new file mode 100644 index 0000000..835b0e3 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/authentication.md @@ -0,0 +1,92 @@ +# Аутентификация + +**Теги:** `B2B` `B2C` `H2H` + +При входе через Alfa ID для вашего пользователя доступны следующие способы аутентификации: + +- логин и пароль; +- QR-код; +- электронная подпись; +- биометрия. + +--- + +### Логин и пароль + +Аутентификация по логину и паролю — пользователь вводит свой логин и пароль. После успешной аутентификации пользователь получает доступ к защищённым ресурсам. + +**Процесс аутентификации:** + +1. Введите свои учётные данные на странице входа. +2. Введите код из СМС. + +--- + +### QR-код + +Аутентификация по QR-коду — это технология, которая позволяет пользователям быстро и безопасно подтверждать свою личность путём сканирования QR-кода. + +**Процесс аутентификации:** + +1. Отсканируйте QR-код камерой мобильного устройства. +2. Подтвердите вход через приложение Альфа-Бизнес Мобайл (АБМ). +3. Введите код из СМС. + +> **Примечание** +> Наличие приложения Альфа-Бизнес Мобайл (АБМ) является условием входа по QR-коду. + +--- + +### Электронная подпись + +Аутентификация с помощью электронной подписи (ЭП) — это технология, основанная на применении средств криптографической защиты информации, для использования которой необходимо наличие токена (USB-носитель) с сертификатом и специализированного программного обеспечения на компьютере. + +Для аутентификации используются следующие виды ЭП: + +- квалифицированная электронная подпись (КЭП); +- сертификат Альфа-Банка (неквалифицированная электронная подпись, НЭП). + +#### Квалифицированная электронная подпись (КЭП) + +**Процесс аутентификации:** + +1. Вставить токен с сертификатом КЭП в компьютер. +2. Нажать на кнопку «Войти по токену». +3. Нажать на кнопку «С сертификатом КЭП». +4. Выбрать необходимый сертификат из списка. +5. Ввести пароль (при его наличии) от сертификата. +6. Ввести пароль от учётной записи Банка. + +#### Сертификат Альфа-Банка (НЭП) + +**Процесс аутентификации:** + +1. Вставить токен с сертификатом Альфа-Банка (НЭП) в компьютер. +2. Нажать на кнопку «Войти по токену». +3. Нажать на кнопку «С сертификатом Альфа-Банка». +4. Выбрать необходимый сертификат из списка. +5. Ввести пароль от токена. +6. Ввести пароль от учётной записи Банка. + +--- + +### Биометрия + +Аутентификация с помощью биометрических данных является одним из наиболее надёжных методов защиты информации. Она позволяет идентифицировать пользователя на основе его уникальных физических характеристик (отпечаток пальца, лицо). + +**Процесс аутентификации:** + +1. Выберите «Быстрый вход». +2. Приложите палец или отсканируйте лицо. + +> **Примечание** +> +> 1. Данный способ аутентификации работает на устройствах, поддерживающих работу с биометрическими данными. +> 2. Для того чтобы использовать данный способ аутентификации, необходимо предварительно пройти регистрацию биометрических данных при входе через логин и пароль. + +--- + +### Навигация + +- [← Что такое Alfa ID](/products/alfa-api/documentation/articles/alfa-id/articles/intro/intro) +- [Кнопка входа по Alfa ID →](/products/alfa-api/documentation/articles/alfa-id/articles/button/button) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/client_credentials_flow/how_to_use_ccf.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/client_credentials_flow/how_to_use_ccf.md new file mode 100644 index 0000000..ebc8dc2 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/client_credentials_flow/how_to_use_ccf.md @@ -0,0 +1,114 @@ +# Как использовать CCF (Client Credentials Flow) + +**Теги:** `B2B` `B2C` `H2H` + +Вы можете использовать **Client Credentials Flow** в своих приложениях для получения доступа к определённому числу сервисов Alfa API. Доступ осуществляется с помощью `access_token`, который Вы получаете без участия пользователя. + +### Доступные методы + +Методы, доступные с помощью `access_token`, полученного по Client Credentials Flow: + +- [Платежи через СБП](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2c/articles/intro/intro) +- [Кредиты](/products/alfa-api/documentation/articles/scoring/scoring) +- [Оплата покупок через СБП](/products/alfa-api/documentation/articles/sbp/articles/sbp-c2b/articles/intro/intro) +- [Операции СБП для юрлиц](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2b/articles/intro/intro) +- [Дебетовая анкета](/products/alfa-api/documentation/articles/debit-cards/articles/intro/intro) +- [Цифровые финансовые активы (ЦФА)](/products/alfa-api/documentation/articles/dfa/dfa) + +> **Важно:** Client Credentials Flow не позволяет использовать методы, которые содержат персональные данные пользователя или банковскую тайну. В соответствии с регуляторными требованиями, Банк обязан проверить полномочия представителя на получение такой информации. + +--- + +## Шаги авторизации + +1. **Получение токена доступа** (см. детали ниже). + +### Дополнительно + +При необходимости вы можете [отозвать токен](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token). + +--- + +## Техническая спецификация API + +### Получение токена доступа + +**Endpoint:** `POST https://baas.alfabank.ru/oidc/token` + +#### Заголовки (Headers) + +| Название | Обязательно | Значение | +| :------------- | :---------- | :---------------------------------- | +| `Content-Type` | Да | `application/x-www-form-urlencoded` | +| `Accept` | Да | `application/json` | + +#### Параметры тела запроса (Request Body) + +| Параметр | Тип | Описание | +| :-------------- | :----- | :---------------------------------------------------------------------------------------------------------- | +| `grant_type` | string | Тип гранта. Для CCF обычно используется `client_credentials` (в данном примере указан `authorization_code`) | +| `client_id` | uuid | Идентификатор партнёрского сервиса | +| `client_secret` | string | Секретный ключ партнёрского сервиса | +| `code` | uuid | Код авторизации | +| `redirect_uri` | string | URI перенаправления | + +--- + +## Примеры кода + +### cURL + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' +``` + +### Python + +```python +import requests + +url = "https://baas.alfabank.ru/oidc/token" +payload = 'grant_type=authorization_code&code=8962c304-89b1-11ec-a8a3-0242ac120002&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&client_secret=Qwerty1234567890Qwerty1234567890!&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode' +headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json' +} + +response = requests.request("POST", url, headers=headers, data=payload) +print(response.text) +``` + +--- + +## Возможные ошибки (параметр `error`) + +| Значение | Описание | +| :----------------------- | :------------------------------------------------------------------ | +| `invalid_request` | Отсутствует обязательный параметр или неверный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный ID или неверный secret). | +| `invalid_grant` | Недействительный код авторизации или несоответствие redirect_uri. | +| `unsupported_grant_type` | Тип grant_type не поддерживается сервером. | +| `internal_error` | Внутренняя ошибка сервера. | + +--- + +## Структура ответа (Success 200 OK) + +При успешном запросе возвращается JSON со следующими полями: + +- `access_token`: Токен доступа (JWT). Действует 1 час. +- `refresh_token`: Токен для обновления access_token. +- `id_token`: Идентификационный токен. +- `expires_in`: Срок жизни токена в секундах (3600). +- `token_type`: Тип токена (Bearer). + +--- + +_Документация Alfa API. [Портал разработчика](https://developers.alfabank.ru)_ diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/client_credentials_flow/obteining_access_token_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/client_credentials_flow/obteining_access_token_POST.md new file mode 100644 index 0000000..e69de29 diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/client-consents_GET.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/client-consents_GET.md new file mode 100644 index 0000000..7a9b960 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/client-consents_GET.md @@ -0,0 +1,119 @@ +# Данные по согласиям пользователей + +**Теги:** `B2B` `B2C` `H2H` + +## Эндпоинты + +### Песочница + +`GET https://sandbox.alfabank.ru/oidc/client-consents` + +### Пром + +`GET https://baas.alfabank.ru/oidc/client-consents` + +--- + +## Описание + +Данный метод можно включать в `scope` с типом гранта [Client Credentials Flow](/products/alfa-api/documentation/articles/alfa-id/articles/ccf/articles/intro/intro) или с типом гранта [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/acf). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :-------------------- | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/json | + +### QUERY + +| Атрибут | Тип | Обязательность | Описание | +| :--------------------- | :------ | :------------- | :------------------------------------------------------------------------------------ | +| **clientId** | string | optional | Идентификатор партнёрского сервиса | +| **sub** | string | optional | Идентификатор субъекта (пользователя) | +| **organizationIdHash** | string | optional | Хэш идентификатора ЮЛ (организации) | +| **isActive** | boolean | optional | Признак активного согласия | +| **limit** | integer | optional | Количество объектов на одной странице. Значение по умолчанию: 1000 | +| **offset** | integer | optional | Количество объектов в списке, которые необходимо пропустить. Значение по умолчанию: 0 | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/oidc/client-consents?clientId={clientId}&sub={sub}&organizationIdHash={organizationIdHash}&isActive={isActive}&limit={limit}&offset={offset}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK + +**HEADERS** + +- **Content-Type**: `application/json` (optional) + +**BODY** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **pagination** | object | Данные пагинации | +| ∟ **limit** | number | Количество записей на одной странице | +| ∟ **offset** | number | Количество записей в списке, которые были пропущены | +| ∟ **totalCount** | number | Общее количество записей | +| **items** | array of objects | Массив объектов результата | +| ∟ **createDateTime** | string | Дата и время создания (required) | +| ∟ **sub** | string | Идентификатор субъекта (пользователя) (required) | +| ∟ **organizationIdHash** | string | Хэш идентификатора ЮЛ (организации) (optional) | +| ∟ **clientId** | string | Идентификатор партнёрского сервиса (required) | +| ∟ **isActive** | boolean | Признак активного согласия (required) | +| ∟ **expireDate** | string | Дата окончания действия (required) | + +#### Пример ответа 200 + +```json +{ + "pagination": { + "limit": 1, + "offset": 0, + "totalCount": 1000 + }, + "items": [ + { + "createDateTime": "2022-10-10T12:15:10", + "sub": "3228e68e-cc34-4b82-b43d-49112b5d9d3e", + "organizationIdHash": "665f4c5837ea35d1b081f4feb05de61522b6854c2268583f3f5865a0981f9268", + "clientId": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "isActive": true, + "expireDate": "2023-04-10" + } + ] +} +``` + +--- + +### Ошибки + +| Код | Описание | Возможные значения `error` | +| :------ | :-------------------- | :------------------------------------------------------------ | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | + +--- + +## Навигация + +- ← [Отзыв токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token) +- → [Экранирование](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening) + +--- + +_Документация Alfa API. [Официальный портал](https://developers.alfabank.ru/)_ diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/revoke-token_POST.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/revoke-token_POST.md new file mode 100644 index 0000000..438e7ae --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/revoke-token_POST.md @@ -0,0 +1,76 @@ +# Отзыв токена доступа + +**Теги:** `B2B` `B2C` `H2H` + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :--------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/revoke` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/revoke` | + +## Описание + +Данный метод используется для отзыва `access_token` и `refresh_token`. +В случае отзыва `refresh_token`, `access_token` будет также отозван. + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------ | :----- | :------------- | :----------------------------------------------------------------------------------------------------------------------- | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | +| **token** | string | required | Отзываемый токен | +| **token_type_hint** | string | optional | Тип отзываемого токена. Возможные значения:
• `access_token` — токен доступа;
• `refresh_token` — токен обновления | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/revoke' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'token=string' \ +--data-urlencode 'token_type_hint=refresh_token' +``` + +--- + +## Параметры ответа + +### 200 OK + +Нет тела ответа. + +### 400 Bad Request + +**Headers:** + +- `Content-Type: application/json` (optional) + +**Body:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Возможные значения:
• `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Навигация + +- [← Проверка подписи](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/signature-checking/signature-checking) +- [Данные по согласиям пользователей →](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/client-consents/v1/client-consents) + +--- + +_Документация Alfa ID / Расширение сценариев_ diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/signature-checking.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/signature-checking.md new file mode 100644 index 0000000..625b7be --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/expansion/signature-checking.md @@ -0,0 +1,155 @@ +# Проверка подписи + +Проверить подпись можно для трех сущностей: + +- `id_token`; +- `access_token`; +- `userinfo`. + +Партнёр API получает ответ в формате сформированного токена **JWS**, который состоит из: + +- **Заголовка (Header)**, содержащего алгоритм подписи, идентификатор ключа и тип токена; +- **JSON-объекта (Payload)**, в котором перечислены клэймы полезной нагрузки; +- **Электронной подписи (Signature)**, содержащей подпись данных секретным ключом, парным открытому ключу, выпущенному для Alfa ID. + +### Декодирование компактной сериализации JWS + +JWS формируется из трех составляющих и представляет структуру вида: +`Base64URL(Header).Base64URL(Payload).Base64URL(Signature)` + +--- + +#### Пример access_token + +**Закодированный токен:** +`eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsInNjb3BlX3NlcnZpY2VzIjpbInBheW1lbnQiLCJzdGF0ZW1lbnQiXSwiaWF0IjoxNjMxNjYzMDYzLCJzY29wZV9jbGFpbXMiOlsibmFtZSIsImdpdmVuX25hbWUiLCJmYW1pbHlfbmFtZSIsIm1pZGRsZV9uYW1lIiwiZW1haWwiLCJwaG9uZV9udW1iZXIiXX0.WVr5xkQSEGqpPXN3aIo0zHZLDL0vvtxEEQ83BrgJo7l0BjjALeGDRYENF2bL8j3n1pXRnduiBQcYNV6teBhESI8V_8kd7Kh7LTePkJWadPSvD__KskC69b4XZ-zN-IQ73NmAcBDStnnhSXGKL6xhdRy-TGiAoKPsRWiDVntsDlpCQNHAt3tJk8q_SQS4S1k6qju9eJ2GFkgmd6z8rR2vaBykaOF0K61ltksw6YgXhuek3OlYkqIAivyKYl59uio8zMpJk-YrPlmawwmvWPF0vKhaLj8Mvn4mVMsVSfuVVKP2ksHG0MAlWpO3Sh9GoKO4d6TQplJ4vgIIeNx-44npqw` + +**Раскодированные данные:** + +**Header** + +```json +{ + "kid": "alfa-test-jwt", + "typ": "JWT", + "alg": "RS256" +} +``` + +**Payload** + +```json +{ + "sub": "3228e68e-cc34-4b82-b43d-49112b5d9d3e", + "aud": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "iss": "https://id.alfabank.ru", + "exp": 1631666663, + "scope_services": ["payment", "statement"], + "iat": 1631663063, + "scope_claims": [ + "name", + "given_name", + "family_name", + "middle_name", + "email", + "phone_number" + ] +} +``` + +**Signature** + +```javascript +RSASHA256( + base64UrlEncode(header) + "." + base64UrlEncode(payload), + your - 256 - bit - secret, +); // secret base64 encoded +``` + +--- + +#### Пример JWS идентификационного токена id_token + +Каждая часть, разделённая точкой, должна декодироваться отдельно с использованием алгоритма Base64URL Encoding. + +**Закодированный токен:** +`eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ .eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY3IiOiJMb0EzIiwiYXpwIjoiMGNlZTA2ODMtODVhZS00OWYyLWE2M2QtMjlmOTdhYWQxOTExIiwiYXV0aF90aW1lIjoxNjMxNjYzMDUzLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsImlhdCI6MTYzMTY2MzA2Mywibm9uY2UiOiJuLTBTNl9XekEyTWoifQ .xBE6LEUxOKleHCZVQacldJfKr5KtyyvJKCCmInqapmRJ_aRF-cEoVfpJd_kxlNmJYT7AcjMMppovNkmhB49VL5DK8FhF0fvRgLskKR9Eohy4eiC8ued03Z1LyLz1H7EcKSkusaCIajzIvxxZfVtSHI4jmgLg6ItXPdZgIDUWINgESkl6I7IP5CbfONHweNnbkWEOEzxDgGGnxxtPxrWVoPVP-ijUeUSH_iESHfrhY_ePRMYi2If62IsKX_0GT5BHRYOhXVDZ9fyn5fRCvg8_QoCykDVIOZMtWQ3w4TadqS0dfMlsLBxkVbVftzH2fWRLTCX3SJ5AXiytHkpow8V45w` + +**Раскодированные данные:** + +**Header** + +```json +{ + "kid": "alfa-test-jwt", + "typ": "JWT", + "alg": "RS256" +} +``` + +**Payload** + +```json +{ + "sub": "3228e68e-cc34-4b82-b43d-49112b5d9d3e", + "aud": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "acr": "LoA3", + "azp": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "auth_time": 1631663053, + "iss": "https://id.alfabank.ru", + "exp": 1631666663, + "iat": 1631663063, + "nonce": "n-0S6_WzA2Mj" +} +``` + +--- + +#### Пример userinfo + +**Закодированный токен:** +`eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJjdXMiOiJVQUFBQUEiLCJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJiaXJ0aGRhdGUiOiIyMDAwLTAyLTIwIiwicm9sZSI6IkFDQ09VTlRBTlQsIE1BTkFHRVIiLCJnZW5kZXIiOiJNQUxFIiwiaWRlbnRpdHlfZG9jdW1lbnRfbmFtZSI6ItCf0LDRgdC_0L7RgNGCINCz0YDQsNC20LTQsNC90LjQvdCwINCg0KQiLCJpZGVudGl0eV9kb2N1bWVudF9udW1iZXIiOjIyMjIyMiwiaXNzIjoiaHR0cHM6XC9cL2JhYXMuYWxmYWJhbmsucnUiLCJpbm4iOjc0MTUxMTExMjIyMiwiZWlvIjp0cnVlLCJnaXZlbl9uYW1lIjoi0KLQtdGB0YIiLCJtaWRkbGVfbmFtZSI6ItCi0LXRgdGC0L7QstC40YciLCJhY3VzIjoiWEFBQUFBIiwiaWRlbnRpdHlfZG9jdW1lbnRfc2VyaWVzIjoxMTExLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY2xjIjoiWEFBQUExIiwidXBkYXRlZF9hdCI6IjIwMjItMDEtMjAiLCJuYW1lIjoi0KLQtdGB0YLQvtCyINCi0LXRgdGCINCi0LXRgdGC0L7QstC40YciLCJwaG9uZV9udW1iZXIiOjc5MTkxMTEyMjMzLCJjbGMiOiJVQUFBQTEiLCJmYW1pbHlfbmFtZSI6ItCi0LXRgdGC0L7QsiIsImVtYWlsIjoiZW1haWxAZW1haWwucnUifQ.WVr5xkQSEGqpPXN3aIo0zHZLDL0vvtxEEQ83BrgJo7l0BjjALeGDRYENF2bL8j3n1pXRnduiBQcYNV6teBhESI8V_8kd7Kh7LTePkJWadPSvD__KskC69b4XZ-zN-IQ73NmAcBDStnnhSXGKL6xhdRy-TGiAoKPsRWiDVntsDlpCQNHAt3tJk8q_SQS4S1k6qju9eJ2GFkgmd6z8rR2vaBykaOF0K61ltksw6YgXhuek3OlYkqIAivyKYl59uio8zMpJk-YrPlmawwmvWPF0vKhaLj8Mvn4mVMsVSfuVVKP2ksHG0MAlWpO3Sh9GoKO4d6TQplJ4vgIIeNx-44npqw` + +**Payload (раскодированный)** + +```json +{ + "cus": "UAAAAA", + "sub": "3228e68e-cc34-4b82-b43d-49112b5d9d3e", + "birthdate": "2000-02-20", + "role": "ACCOUNTANT, MANAGER", + "gender": "MALE", + "identity_document_name": "Паспорт гражданина РФ", + "identity_document_number": 222222, + "iss": "https://baas.alfabank.ru", + "inn": 741511112222, + "eio": true, + "given_name": "Тест", + "middle_name": "Тестович", + "acus": "XAAAAA", + "identity_document_series": 1111, + "aud": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "aclc": "XAAAA1", + "updated_at": "2022-01-20", + "name": "Тестов Тест Тестович", + "phone_number": 79191112233, + "clc": "UAAAA1", + "family_name": "Тестов", + "email": "email@email.ru" +} +``` + +--- + +### Алгоритм проверки подписи + +1. Вычислите хэш-функцию **SHA256** от данных `Base64URL(Header).Base64URL(Payload)`. +2. Дешифруйте данные `Base64URL(Signature)`, используя алгоритм **RS256** и открытый ключ с идентификатором, переданным в Заголовке (Header) в клэйме `kid` (в приведенном выше примере это `alfa-test-jwt`). +3. Сравните вычисленный хэш из 1 шага и дешифрованные данные из 2 шага. Если значения равны, значит, подпись верна. + +**Сертификат для проверки электронной подписи:** [certificate-prod](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/expansion/articles/signature-checking/files/cert.cer) + +--- + +_Навигация:_ +[← Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/ccf/articles/get-access-token/v1/get-access-token) | [Отзыв токена доступа →](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token) diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/screening_eg_character_shielding.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/screening_eg_character_shielding.md new file mode 100644 index 0000000..103288c --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/screening_eg_character_shielding.md @@ -0,0 +1,70 @@ +Вот преобразованный контент страницы в формат Markdown. Я сохранил структуру, иерархию заголовков, примеры кода и таблицу кодировки. + +--- + +# Экранирование + +**Теги:** `B2B` `B2C` `H2H` + +**Путь:** [Главная](https://developers.alfabank.ru/) / Alfa ID / Экранирование + +--- + +**Экранирование специальных символов** — это процесс преобразования специальных символов (например, кавычек, пробелов, знаков препинания) в их соответствующие эквиваленты для передачи данных через различные протоколы и форматы. + +Процентное кодирование или кодирование URI-адресов представляет собой метод кодирования произвольных данных с использованием ограниченных символов US-ASCII, разрешённых в URI. + +Синтаксис URI содержит зарезервированные символы (двух типов) и незарезервированные символы. + +### Зарезервированные символы + +* **gen-delims**: `":"`, `"/"`, `"?"`, `"# "`, `"["`, `"]"`, `"@"` — символы, разделяющие URI на крупные компоненты. +* **sub-delims**: `"!"`, `"$ "`, `"&"`, `"' "`, `"("`, `")"`, `"* "`, `"+"`, `","`, `";"`, `"="` — символы, разделяющие крупный компонент на более мелкие составляющие. + +### Незарезервированные символы + +В общем случае незарезервированные символы — это `ALPHA`, `DIGIT`, `"-"`, `"."`, `"_"`, `"~"`, где `ALPHA` — это буквы, а `DIGIT` — десятичные цифры. + +Если символ из набора зарезервированных символов используется в другом контексте, то он должен быть закодирован в процентах. Процентное кодирование зарезервированного символа представляет собой замену/преобразование символа в соответствующее ему значение. + +Например, зарезервированный символ `"/"` может быть заменен следующими символами: `%2F`. + +--- + +### Примеры запросов + +#### Пример запроса без экранирования +```bash +https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&redirect_uri=https://wwww.partner.ru/code&scope=openid&state=abcdef +``` + +#### Пример запроса с экранированием +```bash +https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode&scope=openid&state=abcdef +``` + +--- + +### Таблица кодирования символов + +| Символ | ANSI (Percent-encoding) | +| :--- | :--- | +| `~` | `%7E` | +| `` ` `` | `%60` | +| `'` | `%27` | +| `"` | `%22` | +| `@` | `%40` | +| `?` | `%3F` | +| `!` | `%21` | +| `#` | `%23` | +| `№` | `%B9` | +| `$` | `%24` | + +--- + +### Навигация +* ← [Данные по согласиям пользователей](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/client-consents/v1/client-consents) +* [API Key](/products/alfa-api/documentation/articles/api-key/api-key) → + +--- +*Документация Alfa API* diff --git a/_docs/alfabank/payin_and_kyc/Alfa_ID/what_is_alfa_id.md b/_docs/alfabank/payin_and_kyc/Alfa_ID/what_is_alfa_id.md new file mode 100644 index 0000000..99b09ef --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Alfa_ID/what_is_alfa_id.md @@ -0,0 +1,83 @@ +# Что такое Alfa ID + +**Alfa ID** — единая учётная запись пользователя ЮЛ (юридического лица) / ФЛ (физического лица), которая помогает пользователям входить на ваш сайт или в приложение, а также в продукты и сервисы Альфа-Банка. + +### Преимущества для пользователей + +- Простая и быстрая аутентификация на сайтах и в приложениях; +- Единый и безопасный аккаунт; +- Упрощение процесса покупки или подачи заявки; +- Безопасность персональных данных; +- Не нужно запоминать множество паролей. + +### Преимущества для партнёров + +- Простая и быстрая аутентификация, выше конверсия на вход; +- Быстрое получение актуальных данных пользователя от Банка; +- Автозаполнение форм и заявок; +- Проверка реальности пользователя; +- Индустриальные стандарты защиты данных и персональной информации; +- Отсутствие необходимости хранить персональные данные на своей стороне. + +### Рекомендуемые браузеры для работы с Alfa ID + +- **Яндекс Браузер** версии 21 и выше; +- **Safari** версии 16 и выше; +- **Google Chrome** версии 117 и выше. + +--- + +## Инструкция: Настройка прав доступа + +По умолчанию доступ к Порталу разработчика имеет только руководитель вашей организации. Для предоставления доступа другим пользователям (например, разработчикам), необходимо создать соответствующую роль в «Альфа-Бизнес». + +> **Внимание для ИП:** +> Права разработчика можно назначить от имени самого ИП (роль «Руководитель») или от имени любого другого сотрудника с ролью «Руководитель» (потребуется подтверждение от владельца ИП). + +### Шаг 1. Перейдите в раздел «Пользователи и роли» + +На главном экране Альфа-Бизнес перейдите в настройки компании. +![image](files/1.png) +![image](files/2.png) +В разделе **Моя компания** выберите карточку **Пользователи и роли**. +![image](files/3.png) + +### Шаг 2. Создайте новую роль + +Нажмите **Создать роль**. +![image](files/4.png) +Укажите название роли (например, «Разработчик API»). +![image](files/5.png) + +Далее настройте права. Рекомендуется создавать роль на основании прав руководителя, сбросив лишнее: + +1. Нажмите **Снять все**, чтобы сбросить права руководителя. + ![image](files/6.png) +2. В разделе **Обслуживание бизнеса** выберите **Alfa API**, указав необходимые права. + ![image](files/7.png) +3. Нажмите **Создать роль** для сохранения. + +### Шаг 3. Назначьте роль разработчику + +В разделе **Пользователи** нажмите на три точки справа от нужного сотрудника и выберите **Сменить роль**. +![image](files/9.png) + +Выберите созданную роль и нажмите **Сменить**. +![image](files/11.png) + +Подтвердите смену роли кодом из СМС. +![image](files/12.png) + +После успешной смены в записи пользователя отобразится статус **Подключён**. Теперь пользователь может работать с Порталом разработчика. +![image](files/13.png) + +--- + +## Требования к полномочиям для авторизации + +Для корректной работы H2H-интеграций ключ доступа (`access_token` / `API Key`) должен получать пользователь, обладающий правами на конкретные сервисы: + +- **При использовании ACF H2H:** Авторизацию в Alfa ID должен проходить пользователь, у которого в Альфа-Бизнес настроены полномочия на использование выбранных `scopes`. +- **При использовании API Key:** Выпускать ключ должен пользователь, имеющий права на те продукты, которые выбраны при выпуске ключа. + +**Пример:** Если у разработчика есть права на редактирование интеграций, но нет прав на «Просмотр выписки», то выпущенный им API Key для сервиса `transactions` работать не будет. diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/create-webhook.md b/_docs/alfabank/payin_and_kyc/Вебхуки/create-webhook.md new file mode 100644 index 0000000..48b4bed --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/create-webhook.md @@ -0,0 +1,120 @@ +# Создание вебхука + +**Типы интеграции:** `B2B` `B2C` `H2H` +**Метод:** `POST` + +Сервис информирования при наступлении в системе события, на которое подписан Партнёр API. + +## Эндпоинты + +| Окружение | URL | +| :------------ | :------------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/v1/webhooks` | +| **Пром** | `POST https://baas.alfabank.ru/api/v1/webhooks` | + +--- + +## Scope + +`scope` события, на которое подписываетесь, с допустимыми значениями можно посмотреть [здесь](/products/alfa-api/documentation/articles/webhooks/webhooks). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | **required** | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | **required** | `application/json` | +| **Content-Type** | `string` | **required** | `application/json` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :---------------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **object** | `string` | **required** | Объект/сущность, на который партнёр API хочет подписаться. Возможные значения:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | +| **data** | `object` | optional | Дополнительные данные по вебхукам. Список полей зависит от события. Для `jp_sbp_incoming_payments` не заполняется. | +| **data.accounts** | `array of string` | optional | Список счетов. Заполняется при `object: ul_transaction_default`. Если не переданы, вебхук создается на все доступные счета. | +| **callbackUri** | `string` | **required** | URL партнёра. Должен соответствовать хосту `redirect_uri` из настроек Alfa ID (проверка по домену второго уровня). | +| **version** | `integer` | optional | Версия формата данных. Для текущих объектов возможное значение — `1`. | + +--- + +## Пример запроса + +```bash +curl -X POST https://baas.alfabank.ru/api/v1/webhooks \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "object": "ul_transaction_default", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ (201 Created) + +| Атрибут | Тип | Описание | +| :-------------- | :-------- | :------------------------------------------------------------------------ | +| **id** | `uuid` | Идентификатор записи вебхука. | +| **object** | `string` | Сущность подписки (`ul_transaction_default`, `jp_sbp_incoming_payments`). | +| **enabled** | `boolean` | Статус вебхука (`true` — включён, `false` — выключен). | +| **data** | `object` | Дополнительные данные (например, список `accounts`). | +| **callbackUri** | `string` | URL партнёра, на который будет отправлен вебхук. | +| **version** | `integer` | Версия формата данных. | + +**Пример JSON ответа:** + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 +} +``` + +--- + +## Ошибки + +| Код | Описание (error) | Описание ошибки (error_description) | +| :------ | :------------------------ | :-------------------------------------------------------------- | +| **400** | `invalid_request` | Неверные входные параметры запроса. | +| **401** | `invalid_token` | Токен просрочен, отозван или имеет неправильный формат. | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (настройки scope). | +| **403** | `insufficient_privileges` | Нет доступа к `callbackUri` или вебхуки выключены для партнёра. | +| **404** | `unknown_route` | Эндпоинт не найден или неактивен. | +| **429** | — | Too Many Requests (превышение лимита запросов). | +| **500** | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | — | Service Unavailable (сервис временно недоступен). | + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных выше. + +--- + +**Навигация:** +← [Как подключить](/products/alfa-api/documentation/articles/webhooks/articles/intro/intro) | [Редактирование вебхука](/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v1/edit-webhook) → diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/delete-webhook.md b/_docs/alfabank/payin_and_kyc/Вебхуки/delete-webhook.md new file mode 100644 index 0000000..56396b6 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/delete-webhook.md @@ -0,0 +1,98 @@ +Ниже представлен сконвертированный из HTML текст документации в формате Markdown. Все ссылки сохранены, структура таблиц и примеров кода приведена к удобному для чтения виду. + +--- + +# Удаление вебхука + +**Теги:** `B2B` `B2C` `H2H` + +## Эндпоинты + +| Среда | Метод и URL | +| :--- | :--- | +| **Песочница** | `DELETE https://sandbox.alfabank.ru/api/v1/webhooks/{id}` | +| **Пром** | `DELETE https://baas.alfabank.ru/api/v1/webhooks/{id}` | + +### Scope +`scope` события, на которое подписываетесь, с допустимыми значениями можно посмотреть [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/webhooks/webhooks). + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | **required** | Bearer {access_token}, полученный по [Authorization Code Flow](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | **required** | `application/json` | +| **Content-Type** | string | optional | `application/json` | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **id** | uuid | **required** | Идентификатор вебхука | + +### QUERY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **object** | string | **required** | Объект/сущность, на который партнёр API хочет подписаться. Возможные значения:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | + +--- + +## Пример запроса + +```bash +curl -X DELETE https://baas.alfabank.ru/api/v1/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3?object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### 200 — OK +Нет тела ответа. + +### 400 — Bad Request +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +### 401 — Unauthorized +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `invalid_token` — предоставленный токен просрочен, отозван или недействителен | +| **error_description** | string | optional | Описание ошибки | + +### 403 — Forbidden +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки:
• `insufficient_scope` — нет прав (настройки scope);
• `insufficient_privileges` — вебхуки выключены для клиента или сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 404 — Not Found +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `unknown_route` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +### 429 — Too Many Requests +Нет тела ответа. + +### 500 — Internal Server Error +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 503 — Service Unavailable +Нет тела ответа. + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в данной документации. + +--- +**Навигация:** +[← Редактирование вебхука](https://developers.alfabank.ru/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v2/edit-webhook) | [Получение вебхука →](https://developers.alfabank.ru/products/alfa-api/documentation/articles/webhooks/articles/get-webhook/v1/get-webhook) diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/edit-webhook.md b/_docs/alfabank/payin_and_kyc/Вебхуки/edit-webhook.md new file mode 100644 index 0000000..1404ba8 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/edit-webhook.md @@ -0,0 +1,132 @@ +Ниже представлено содержимое документа, преобразованное в структурированный Markdown. + +--- + +# Редактирование вебхука + +**Теги:** `B2B` `B2C` `H2H` +**Версия:** Последняя версия v2 + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `PUT https://sandbox.alfabank.ru/api/v2/webhooks/{id}` | +| **Пром** | `PUT https://baas.alfabank.ru/api/v2/webhooks/{id}` | + +### Scope +`scope` события, на которое подписываетесь, с допустимыми значениями можно посмотреть [здесь](/products/alfa-api/documentation/articles/webhooks/webhooks). + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | `string` | **required** | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | **required** | `application/json` | +| **Content-Type** | `string` | **required** | `application/json` | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **id** | `uuid` | **required** | Идентификатор вебхука | + +### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **object** | `string` | **required** | Объект/сущность для подписки:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей | +| **enabled** | `boolean` | optional | Статус: `true` (включён), `false` (выключен) | +| **organizationIdHash** | `string` | optional | Хэш идентификатора организации | +| **data** | `object` | optional | Дополнительные данные. Для `jp_sbp_incoming_payments` не заполняется. | +| **data.accounts** | `array of string`| optional | Список счетов. При `object: ul_transaction_default` — **обязательно** (передавать все счета). Пустой массив = вебхук на все счета. | +| **callbackUri** | `string` | optional | URL партнёра. Можно менять только `path`, менять `host` нельзя. | +| **version** | `integer` | optional | Версия формата данных. Допустимое значение — `1`. | + +--- + +## Пример запроса + +```bash +curl -X PUT https://baas.alfabank.ru/api/v2/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3 \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'X-Request-ID: {uuid}' \ + -d '{ + "object": "ul_transaction_default", + "enabled": true, + "data": { + "accounts": [ + "40802810401300015422", + "40802810401300015422" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 + }' +``` + +--- + +## Параметры ответа + +### Пример ответа 200 (ОК) + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled by administrator" + } + ] +} +``` + +### Описание полей ответа (200 OK) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **id** | `uuid` | Идентификатор записи | +| **object** | `string` | Сущность подписки (`ul_transaction_default` или `jp_sbp_incoming_payments`) | +| **enabled** | `boolean` | Статус активации | +| **data.accounts** | `array` | Список счетов (для выписок) | +| **callbackUri** | `string` | URL получения уведомлений | +| **statusDescriptions** | `array` | Причины выключения вебхука (если есть) | + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав доступа; `insufficient_privileges` — нет доступа к callbackUri | +| **404** | Not Found | `unknown_route` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +> **Рекомендация:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- +[← Назад к списку: Редактирование вебхука v1](/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v1/edit-webhook) | [Вперёд: Удаление вебхука →](/products/alfa-api/documentation/articles/webhooks/articles/delete-webhook/v1/delete-webhook) diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhook.md b/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhook.md new file mode 100644 index 0000000..8d8fe50 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhook.md @@ -0,0 +1,124 @@ +# Получение вебхука + +**Типы интеграции:** `B2B`, `B2C`, `H2H` +**Версия API:** `v2` (Последняя) + +Метод позволяет получить информацию о конкретном вебхуке по его идентификатору. + +--- + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :----------------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/v2/webhooks/{id}` | +| **Пром** | `GET https://baas.alfabank.ru/api/v2/webhooks/{id}` | + +### Scope + +`scope` события, на которое подписываетесь, с допустимыми значениями можно посмотреть [здесь](/products/alfa-api/documentation/articles/webhooks/webhooks). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | `Bearer {access_token}`, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | optional | `application/json` | + +### PATH (Параметры пути) + +| Атрибут | Тип | Обяз. | Описание | +| :------ | :--- | :------- | :-------------------- | +| **id** | uuid | required | Идентификатор вебхука | + +### QUERY (Параметры строки запроса) + +| Атрибут | Тип | Обяз. | Описание | +| :--------- | :----- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **object** | string | required | Объект/сущность, на который партнер хочет подписаться:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | + +--- + +## Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/v2/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3?object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :--------------------- | :------------ | :------------------------------------------------------------------------ | +| **id** | uuid | Идентификатор записи | +| **object** | string | Объект подписки (`ul_transaction_default` или `jp_sbp_incoming_payments`) | +| **enabled** | boolean | Статус вебхука: `true` — включен, `false` — выключен | +| **organizationIdHash** | string | Хэш идентификатора организации | +| **data** | object | Дополнительные данные. Список полей зависит от события. | +| └ **accounts** | array[string] | Список счетов (для `ul_transaction_default`) | +| **callbackUri** | string | URL партнёра, на который отправляется вебхук | +| **version** | integer | Версия формата данных. Для текущих объектов значение — `1`. | +| **statusDescriptions** | array[object] | Описание статуса выключения вебхука | +| └ **cause** | string | Причина выключения | +| └ **description** | string | Описание причины | + +#### Пример ответа 200: + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled administrator" + } + ] +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Ошибка (`error`) | +| :------ | :------------------ | :--------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (scope) | +| **404** | Not Found | `unknown_route` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +> **Рекомендация:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhooks-list.md b/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhooks-list.md new file mode 100644 index 0000000..94fd957 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/get-webhooks-list.md @@ -0,0 +1,131 @@ +# Получение списка вебхуков + +`B2B` `B2C` `H2H` + +Метод позволяет получить список всех настроенных вебхуков для конкретного объекта подписки. + +### Эндпоинты + +| Окружение | Метод | URL | +| :------------ | :---- | :-------------------------------------------- | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/v2/webhooks` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/v2/webhooks` | + +### Scope + +`scope` события, на которое подписываетесь, с допустимыми значениями можно посмотреть [здесь](/products/alfa-api/documentation/articles/webhooks/webhooks). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | optional | `application/json` | + +### QUERY + +| Атрибут | Тип | Обяз. | Описание | +| :--------- | :------ | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **object** | string | required | Объект/сущность, на который партнёр API хочет подписаться. Возможные значения:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | +| **offset** | integer | optional | Смещение в результатах поиска. | +| **limit** | integer | optional | Количество элементов на странице. | + +### Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/v2/webhooks?offset=20&limit=10&object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +#### Тело ответа (JSON) + +| Атрибут | Тип | Описание | +| :----------------------- | :------ | :---------------------------------------------------------------------------------------------------------- | +| **pagination** | object | Данные пагинации | +| ∟ **limit** | number | Количество объектов на одной странице | +| ∟ **offset** | number | Количество объектов в списке, которые необходимо пропустить | +| ∟ **totalCount** | number | Общее количество записей | +| **items** | array | Массив объектов результата | +| ∟ **id** | uuid | Идентификатор записи | +| ∟ **object** | string | Объект/сущность подписки (`ul_transaction_default`, `jp_sbp_incoming_payments`) | +| ∟ **enabled** | boolean | Статус вебхука: `true` — включён, `false` — выключен | +| ∟ **organizationIdHash** | string | Хэш идентификатора организации | +| ∟ **data** | object | Дополнительные данные. Поле **accounts** (array of string) заполняется при `object: ul_transaction_default` | +| ∟ **callbackUri** | string | URL партнёра, на который отправляется вебхук | +| ∟ **version** | integer | Версия формата данных (возможные значения — `1`) | +| ∟ **statusDescriptions** | array | Описание причин выключения вебхука | +| ∟∟ **cause** | string | Причина выключения | +| ∟∟ **description** | string | Описание причины | + +#### Пример ответа 200 + +```json +{ + "pagination": { + "offset": 45, + "limit": 10, + "totalCount": 100 + }, + "items": [ + { + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled administrator" + } + ] + } + ] +} +``` + +--- + +## Ошибки + +| Код | Описание | Возможные `error` | +| :------ | :------------------ | :--------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (scope) | +| **404** | Not Found | `unknown_route` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа (превышен лимит запросов) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа (сервис временно недоступен) | + +> Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +**Навигация:** +← [Получение вебхука](/products/alfa-api/documentation/articles/webhooks/articles/get-webhook/v2/get-webhook) | [Партнёрский метод для получения вебхуков](/products/alfa-api/documentation/articles/webhooks/articles/partner-webhook/v1/partner-webhook) → diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/partner-webhook.md b/_docs/alfabank/payin_and_kyc/Вебхуки/partner-webhook.md new file mode 100644 index 0000000..2193e0c --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/partner-webhook.md @@ -0,0 +1,136 @@ +# Партнёрский метод для получения вебхуков + +На стороне партнёра должен быть реализован метод **POST** с URL, на который будет отправляться вебхук. Важно, чтобы второй уровень домена совпадал со вторым уровнем домена, который указывали в качестве `redirect_uri` при интеграции с Alfa ID. Подробнее [в инструкции по подключению вебхуков](/products/alfa-api/documentation/articles/webhooks/webhooks). + +### **Авторизация** + +Реализованный метод может быть как открытым, так и закрыт авторизацией. В случае, если метод закрыт авторизацией, необходимо отправить письмо на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru) с данными, как авторизоваться в методе. Для авторизации запросов может использоваться: + +- **Client Credentials Flow** ([RFC 6749](https://datatracker.ietf.org/doc/html/rfc6749)) +- **Basic Authentication** ([RFC 7617](https://datatracker.ietf.org/doc/html/rfc7617)) + +### **Время ответа** + +Метод партнёра должен возвращать ответ не более чем за **300 миллисекунд**. Это оптимальная скорость ответа для обеспечения стабильной работы интеграции и оперативной обработки событий. + +### **Retry-запросы** + +Если метод партнёра отвечает с ошибкой, превышает сконфигурированное время ожидания или Банку не удаётся отправить запрос, то банк отправляет retry-запросы на доставку вебхука. + +**Интервалы повторной отправки:** 30 секунд, 5 минут, 30 минут, 1 час, 3 часа, 6 часов, 12 часов, 24 часа, 48 часов, 72 часа. + +**Возможные причины отправки retry-запроса:** + +- был получен ответ с одним из следующих статусов: 401, 408, 409, 429, 500, 502, 503, 504, 507, 508, 509; +- ответ на запрос не был получен в пределах сконфигурированного времени ожидания (5 секунд); +- не удалось установить TCP-соединение; +- хост недоступен или не отвечает. + +> **Важно:** Для предотвращения отправки Банком лишних retry-запросов необходимо возвращать коды, отличные от 2xx, только при возникновении технических сбоев на стороне партнёра. + +### **Выписки** + +В сервисе ["Выписки по счетам юрлиц"](/products/alfa-api/documentation/articles/transactions/transactions) в методах есть уникальный идентификатор транзакции (`transactionId`). Важно, чтобы партнёр на своей стороне игнорировал задублированные сообщения по этому идентификатору, возвращая код успешной обработки (2xx). + +### **Входящие платежи по СБП для юрлиц** + +В методе ["Получение входящих платежей"](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2b/articles/incoming-payments/v1/incoming-payments) есть уникальный идентификатор операции НСПК (`nspkTransactionId`). Важно игнорировать задублированные сообщения по этому идентификатору, возвращая код успешной обработки (2xx). + +--- + +## Параметры запроса (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :----------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **actionType** | string | required | Действие над объектом. Возможные значения: `create` (создание), `update` (обновление), `delete` (удаление). | +| **eventTime** | string | required | Время, когда произошло событие. | +| **object** | string | required | Объект/сущность подписки: `ul_transaction_default` (выписка), `jp_sbp_incoming_payments` (входящие платежи СБП). | +| **data** | object | required | Данные по вебхукам. Поля зависят от объекта (см. методы [«Получение выписки»](/products/alfa-api/documentation/articles/transactions/articles/statement/v1/statement) или [«Получение входящих платежей»](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2b/articles/incoming-payments/v1/incoming-payments)). | +| **organizationId** | string | optional | Идентификатор организации. | +| **sub** | string | optional | Идентификатор субъекта. | + +--- + +## Пример запроса + +```bash +curl -X POST https://webhook.partner.ru/api/v1/webhook-events \ +-H "Content-Type: application/json" \ +-d '[ + { + "actionType": "create", + "eventTime": "2022-01-12T00:00:00", + "object": "ul_transaction_default", + "organizationId": "vvvvvv", + "sub": "f7490296-1ae1-11ec-9621-0242ac130002", + "data": { + "amount": { + "amount": 1.00, + "currencyName": "RUR" + }, + "amountRub": { + "amount": 1.00, + "currencyName": "RUR" + }, + "correspondingAccount": "30101810200000000593", + "direction": "CREDIT", + "documentDate": "2022-01-12", + "filial": "АО \"АЛЬФА-БАНК\" г Москва", + "number": "178", + "operationCode": "01", + "operationDate": "2022-01-12T00:00:00", + "paymentPurpose": "Перевод собственных средств. НДС не облагается.", + "priority": "5", + "revaln": null, + "uuid": "9084d309-b30b-5083-9a54-d4522472e11a", + "transactionId": "1220112MOCO#DS4001415", + "rurTransfer": { + "cartInfo": { + "documentCode": null, + "documentContent": null, + "documentDate": null, + "documentNumber": null, + "paymentNumber": null, + "restAmount": null + }, + "deliveryKind": "электронно", + "departmentalInfo": { + "uip": "1", + "drawerStatus101": "01", + "kbk": "18210102010011000110", + "oktmo": "12301000", + "reasonCode106": "ТП", + "taxPeriod107": "ГД.01.2022", + "docNumber108": "123", + "docDate109": "12.01.2022", + "paymentKind110": "1" + }, + "payeeAccount": "40702810301300000763", + "payeeBankBic": "044525593", + "payeeBankCorrAccount": "30101810200000000593", + "payeeBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payeeInn": "0140237176", + "payeeKpp": "770801001", + "payeeName": "Полное наименование Орг № 11329", + "payerAccount": "40702810701300000761", + "payerBankBic": "044525593", + "payerBankCorrAccount": "30101810200000000593", + "payerBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payerInn": "0140237176", + "payerKpp": "770801001", + "payerName": "Полное наименование Орг № 11329", + "payingCondition": null, + "purposeCode": "2", + "receiptDate": "2022-01-12", + "valueDate": "2022-01-12" + } + } + } +]' +``` + +--- + +## Параметры ответа + +В случае успешной обработки ответа на стороне клиента необходимо вернуть любой код успешной обработки (**2xx**). diff --git a/_docs/alfabank/payin_and_kyc/Вебхуки/webhooks_intro.md b/_docs/alfabank/payin_and_kyc/Вебхуки/webhooks_intro.md new file mode 100644 index 0000000..aab1806 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Вебхуки/webhooks_intro.md @@ -0,0 +1,57 @@ +# Как подключить вебхуки + +**Теги:** `B2B` `B2C` `H2H` + +Вебхук — это механизм информирования при наступлении в системе события, на которое подписан партнёр API. + +Вебхуки повышают эффективность рабочих процессов. Для получения новой информации достаточно будет создать вебхук, и Банк сам будет отправлять информацию по изменениям состояния системы. + +Используется токен доступа, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/acf) для партнёрских сервисов или по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/acf-h2h) для прямой интеграции. + +--- + +### Инструкция по подключению + +1. **Отправить письмо** на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru) с указанием `callbackUri` и события, на которое хотите подписаться. +2. **Реализовать метод:** Партнёру API на своей стороне необходимо реализовать открытый [Партнёрский метод для получения вебхуков](/products/alfa-api/documentation/articles/webhooks/articles/partner-webhook/v1/partner-webhook). +3. **Подписаться на событие** с помощью метода [«Создание вебхука»](/products/alfa-api/documentation/articles/webhooks/articles/create-webhook/v1/create-webhook). +4. **Управлять вебхуками**, используя следующие методы: + - [Редактирование вебхука](/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v2/edit-webhook) + - [Удаление вебхука](/products/alfa-api/documentation/articles/webhooks/articles/delete-webhook/v1/delete-webhook) + - [Получение вебхука](/products/alfa-api/documentation/articles/webhooks/articles/get-webhook/v2/get-webhook) + - [Получение списка вебхуков](/products/alfa-api/documentation/articles/webhooks/articles/get-lists-webhooks/v2/get-lists-webhooks) + +Инструкция по тестированию вебхуков представлена [здесь](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/intro/intro). + +--- + +### Требования к полю callbackUri + +В поле `callbackUri` необходимо указывать хост, который указывали в качестве `redirect_uri` при интеграции с Alfa ID. Проверка будет проводиться только на соответствие домена второго уровня. + +Это позволяет расширить возможные варианты для `callbackUri`. Например, если в качестве `redirect_uri` был указан [https://partner.ru](https://partner.ru), то можно создать следующие `callbackUri`: + +- [https://partner.ru](https://partner.ru) +- [https://webhook.alfa.partner.ru](https://webhook.alfa.partner.ru) +- [https://webhook.partner.ru](https://webhook.partner.ru) +- [https://webhook.partner.partner.partner.ru](https://webhook.partner.partner.partner.ru) + +> **Важно** +> Для создания вебхука с другим хостом необходимо удалить уже существующий вебхук. + +--- + +### Допустимые значения scope + +| Событие | scope | +| :-------------------------------- | :------------- | +| Операции по счетам | `transactions` | +| Входящие платежи по СБП для юрлиц | `b2b-sbp` | + +--- + +**Дополнительные материалы:** + +- **Предыдущая тема:** [Шифрование TXT ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/text-gost/text-gost) +- **Следующая тема:** [Создание вебхука](/products/alfa-api/documentation/articles/webhooks/articles/create-webhook/v1/create-webhook) +- **Видео-инструкция:** [Смотреть MP4](/assets/developers-portal.docs.alfa-api/articles/webhooks/articles/intro/files/webhooks.mp4) diff --git a/_docs/alfabank/payin_and_kyc/Обмен_файлами/download.md b/_docs/alfabank/payin_and_kyc/Обмен_файлами/download.md new file mode 100644 index 0000000..1a3977e --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Обмен_файлами/download.md @@ -0,0 +1,114 @@ +# Скачивание файла + +**Метки:** `B2B` `B2C` `H2H` + +## Этапы процесса + +1. **Получите ссылку для скачивания файла.** Подробнее в пункте «Получение ссылки». +2. **Выполните запрос на скачивание файла.** Подробнее в пункте «Запрос на скачивание». +3. **Скачивание файла.** + +--- + +## Получение ссылки + +Первым шагом необходимо получить ссылку на скачивание файла в рамках Вашего взаимодействия. Ниже приведен пример получаемой Вами ссылки для скачивания файла с описанием параметров. + +### Атрибуты тела ответа (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :------------------------------------ | :-------------- | :------------- | :------------------------------------------- | +| **downloadFileLinks** | array of object | optional | Ссылка для скачивания файла из Банка | +| └─ **url** | string | optional | Ссылка для скачивания файла | +| └─ **method** | string | optional | Метод, используемый для скачивания файла | +| └─ **detachedSignatureLink** | object | optional | Открепленная ЭЦП содержимого файла | +|     └─ **url** | string | optional | Ссылка для скачивания файла открепленной ЭЦП | +|     └─ **method** | string | optional | Метод для скачивания открепленной ЭЦП | + +### Пример ссылок на скачивание + +```json +{ + "downloadFileLinks": [ + { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ab?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=e78c051fcff1017a68795620c20e50db33126ab8374c2ee9644ef4743b3625c6", + "method": "GET", + "detachedSignatureLink": { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ab.sign?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8", + "method": "GET" + } + }, + { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ac?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=e78c051fcff1017a68795620c20e50db33126ab8374c2ee9644ef4743b3625c6", + "method": "GET", + "detachedSignatureLink": { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ac.sign?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8", + "method": "GET" + } + } + ] +} +``` + +--- + +## Запрос на скачивание + +Для скачивания файла по полученной ссылке необходимо выполнить `http` запрос методом, указанным в параметре `method`, и полученной в параметре `url` ссылкой `https://baas.alfabank.ru/filebox/{bucketName}/{objectKey}` с параметрами запроса. + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------- | :----- | :------------- | :------------------------- | +| **Accept** | string | required | `*/*` | +| **Content-Length** | string | required | 1024 | +| **Content-Type** | string | optional | `application/octet-stream` | + +#### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :----- | :------------- | :-------------------------------- | +| **bucketName** | string | required | Имя bucket'а для сохранения файла | +| **objectKey** | string | required | Имя файла | + +#### QUERY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :------ | :------------- | :------------------------------------------------------- | +| **X-Amz-Date** | string | required | Дата и время генерации ссылки | +| **X-Amz-Expires** | integer | required | TTL ссылки (в секундах) относительно времени её создания | +| **X-Amz-Credential** | string | required | Данные об учётной записи s3 и подписи запроса | +| **X-Amz-Algorithm** | string | required | Алгоритм подписи запроса | +| **X-Amz-Signature** | string | required | Подпись запроса | +| **Content-Length** | integer | required | Размер содержимого файла | + +### Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ab?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=e78c051fcff1017a68795620c20e50db33126ab8374c2ee9644ef4743b3625c6 \ + -H 'Accept: */*' \ + -H 'Content-Length: 1024' \ + -H 'Content-Type: application/octet-stream' +``` + +--- + +## Параметры ответа + +| Код | Описание | Тело ответа | +| :---------------------------- | :------------------------ | :---------------------------------------------------------------------------------------------- | +| **200 OK** | Успешное скачивание | Нет тела ответа | +| **400 Bad Request** | Ошибка в запросе | `{"error": "Код ошибки"}` | +| **403 Forbidden** | Доступ запрещен | `{"error": "Время жизни ссылки истекло / Используется некорректный метод или ссылка изменена"}` | +| **404 Not Found** | Файл не найден | `{"error": "Код ошибки"}` | +| **500 Internal Server Error** | Внутренняя ошибка сервера | `{"error": "Код ошибки"}` | + +--- + +### См. также: + +- [Требования и ограничения](/products/alfa-api/documentation/articles/secure-file-transfer/articles/intro/intro) +- [Загрузка файла](/products/alfa-api/documentation/articles/secure-file-transfer/articles/upload/v1/upload) +- [Официальный портал разработчиков Alfa-Bank](https://developers.alfabank.ru/) diff --git a/_docs/alfabank/payin_and_kyc/Обмен_файлами/requirements_and_restrictions.md b/_docs/alfabank/payin_and_kyc/Обмен_файлами/requirements_and_restrictions.md new file mode 100644 index 0000000..8819299 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Обмен_файлами/requirements_and_restrictions.md @@ -0,0 +1,44 @@ +# Требования и ограничения + +**Область применения:** `B2B`, `B2C`, `H2H` +**Раздел:** Обмен файлами + +Механизм для загрузки и скачивания файлов. В рамках продуктового метода API, который предполагает загрузку или скачивание файлов, Вы получите атрибут `downloadFileLinks`, который используется для скачивания файла, или атрибут `uploadFileLinks`, который используется для загрузки файла. + +### Ограничения + +1. По одной ссылке можно загрузить только один файл. +2. Для загрузки нескольких файлов необходимо поместить их в архив формата `.zip` (без пароля), либо загружать файлы отдельными загрузками (каждая в рамках своей задачи, переиспользовать ссылку нельзя). + +### Форматы и размеры файлов + +1. Для файлов, чей `MIME-тип = text/plain`, максимальный размер одного файла — **250 Мбайт**. +2. Для файлов, чей `MIME-тип ≠ text/plain`, максимальный размер одного файла — **60 Мбайт**. + +### Время жизни ссылки + +Ссылка содержит в себе параметр с датой и временем генерации ссылки `X-Amz-Date`. + +- **Формат параметра:** `YYYYMMDDTHHMISSZ`. +- **Длительность:** Время жизни ссылки указывается в секундах параметром `X-Amz-Expires`. + +Отсчёт времени жизни идет от времени генерации ссылки. + +--- + +## Навигация + +- [← SDK для подписи](/products/alfa-api/documentation/articles/sdk/articles/signature/v1/signature) +- [Скачивание файла →](/products/alfa-api/documentation/articles/secure-file-transfer/articles/download/v1/download) + +--- + +### Структура раздела «Обмен файлами» + +- **Требования и ограничения** (текущая страница) +- [Скачивание файла](/products/alfa-api/documentation/articles/secure-file-transfer/articles/download/v1/download) +- [Загрузка файла](/products/alfa-api/documentation/articles/secure-file-transfer/articles/upload/v1/upload) + +--- + +_Документация Alfa-Bank (Alfa API)_ diff --git a/_docs/alfabank/payin_and_kyc/Обмен_файлами/upload.md b/_docs/alfabank/payin_and_kyc/Обмен_файлами/upload.md new file mode 100644 index 0000000..51f7c11 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Обмен_файлами/upload.md @@ -0,0 +1,124 @@ +# Загрузка файла + +**Теги:** `B2B` `B2C` `H2H` + +Процесс загрузки файла состоит из трех основных этапов: + +1. **Получите ссылку для загрузки файла** (Подробнее в пункте «Получение ссылки») +2. **Выполните запрос на загрузку файла** (Подробнее в пункте «Запрос на загрузку») +3. **Загрузка файла** + +--- + +## Получение ссылки + +Первым шагом необходимо получить ссылку на загрузку файла в рамках Вашего взаимодействия. Ниже приведен пример получаемой Вами ссылки для загрузки файла с описанием параметров. + +### Атрибуты ответа (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :------------------ | :---------------- | :------------- | :------------------------------------- | +| **uploadFileLinks** | `array of object` | optional | Ссылка для загрузки файла в Банк | +| ↳ **url** | `string` | optional | Ссылка для загрузки файла | +| ↳ **method** | `string` | optional | Метод, используемый для загрузки файла | + +### Пример ссылок на загрузку + +```json +{ + "uploadFileLinks": [ + { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ab?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8", + "method": "PUT" + }, + { + "url": "https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90ab-cdef-1234-1234567890ac?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8", + "method": "PUT" + } + ] +} +``` + +--- + +## Запрос на загрузку + +Для загрузки файла по полученной ссылке необходимо выполнить `http` запрос методом, указанным в параметре `method`, и полученной в параметре `url` ссылкой: +`https://baas.alfabank.ru/filebox/{bucketName}/{objectKey}` с параметрами запроса. + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------- | :------- | :------------- | :------------------------- | +| **Accept** | `string` | **required** | `*/*` | +| **Content-Length** | `string` | **required** | Например: `1024` | +| **Content-Type** | `string` | optional | `application/octet-stream` | + +#### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :------- | :------------- | :-------------------------------- | +| **bucketName** | `string` | **required** | Имя bucket'а для сохранения файла | +| **objectKey** | `string` | **required** | Имя файла | + +#### QUERY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :-------- | :------------- | :------------------------------------------------------- | +| **X-Amz-Date** | `string` | **required** | Дата и время генерации ссылки | +| **X-Amz-Expires** | `integer` | **required** | TTL ссылки (в секундах) относительно времени её создания | +| **X-Amz-Credential** | `string` | **required** | Данные об учётной записи s3 и подписи запроса | +| **X-Amz-Algorithm** | `string` | **required** | Алгоритм подписи запроса | +| **X-Amz-Signature** | `string` | **required** | Подпись запроса | +| **Content-Length** | `integer` | **required** | Размер содержимого файла | + +### Пример запроса + +```bash +curl -X PUT https://baas.alfabank.ru/filebox/secure-file-transfer.incoming-files.to-processing/12345678-90AB-CDEF-1234-1234567890AB?X-Amz-Date=20230608T152952Z&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fbaas%2Fs3%2Faws4_request&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 \ + -H 'Accept: */*' \ + -H 'Content-Length: 1024' \ + -H 'Content-Type: application/octet-stream' \ + --data-binary 'Выписка по счету.pdf' +``` + +--- + +## Параметры ответа + +### 200 OK + +_Нет тела ответа_ + +### 400 Bad Request + +| Атрибут | Тип | Обязательность | Описание | +| :-------- | :------- | :------------- | :--------- | +| **error** | `string` | **required** | Код ошибки | + +### 403 Forbidden + +| Атрибут | Тип | Обязательность | Описание | +| :-------- | :------- | :------------- | :------------------------------------------------------------------------------------------- | +| **error** | `string` | **required** | Код ошибки. Время жизни ссылки истекло / Используется некорректный метод или ссылка изменена | + +### 404 Not Found + +| Атрибут | Тип | Обязательность | Описание | +| :-------- | :------- | :------------- | :--------- | +| **error** | `string` | **required** | Код ошибки | + +### 500 Internal Server Error + +| Атрибут | Тип | Обязательность | Описание | +| :-------- | :------- | :------------- | :--------- | +| **error** | `string` | **required** | Код ошибки | + +--- + +**Навигация:** + +- [← Скачивание файла](/products/alfa-api/documentation/articles/secure-file-transfer/articles/download/v1/download) +- [Для чего это нужно →](/products/alfa-api/documentation/articles/signature-encryption/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/authorization.md b/_docs/alfabank/payin_and_kyc/Общая_информация/authorization.md new file mode 100644 index 0000000..629327e --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/authorization.md @@ -0,0 +1,32 @@ +# Авторизация + +Теги: `B2B` `B2C` `H2H` + +--- + +Получить доступ к продуктам и сервисам Alfa API можно двумя способами: с помощью Alfa ID или API Key. + +Выбор способа авторизации зависит от типа интеграции, используемых вами продуктов и сервисов, требований безопасности и настроек вашей интеграции. + +## Alfa ID + +`B2B` `B2C` `H2H` + +Этот способ подходит для любого типа интеграций и позволяет работать со всеми продуктами и сервисами Alfa API. Контроль безопасности обеспечивается за счёт использования токенов с коротким сроком действия и проведения аутентификации пользователей. + +Подойдёт вам в следующих случаях: + +•вы хотите выполнять операции по другим организациям (партнёрская интеграция);•вы хотите выполнять операции по своей организации (H2H-интеграция) и вам необходимо, чтобы ваши сотрудники проходили аутентификацию для получения доступа к продуктам и сервисам Alfa API. +## API Key + +`H2H` + +Это упрощённый способ авторизации запросов без аутентификации сотрудников вашей организации, который не требует регулярного обновления ключа доступа. Подходит для выполнения операций по своей организации. Контроль безопасности обеспечивается за счёт того, что запросы принимаются только с ваших доверенных серверов. + +Доступные с помощью этого способа авторизации продукты и сервисы можно посмотреть [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/api-key/api-key). + +Использование упрощённого способа авторизации будет оптимальным вариантом, если у вас H2H-интеграция, использующая продукты и сервисы, доступные с помощью `API Key` , и вам не требуется аутентификация сотрудников для доступа к продуктам и сервисам Alfa API. + +Подробнее о способах авторизации можно прочитать в статьях ниже. + +[Alfa ID](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/intro/intro)[API Key](https://developers.alfabank.ru/products/alfa-api/documentation/articles/api-key/api-key) diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/channel_protection.md b/_docs/alfabank/payin_and_kyc/Общая_информация/channel_protection.md new file mode 100644 index 0000000..59877f2 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/channel_protection.md @@ -0,0 +1,17 @@ +# Защита канала + +Теги: `B2B` `B2C` `H2H` + +--- + +## Введение + +Защита данных с применением криптографических преобразований - одно из решений проблем информационной безопасности. Механизмы шифрования и дешифрования канала обеспечивает надёжность передачи информации. Защитить канал можно, используя асимметричные алгоритмы шифрования данных (RSA-сертификат) и транспортную подпись. + +## Шифрование канала + +Шифрование канала происходит исходя из выбора метода шифрования. Это может быть: + +•шифрование с применением сертификата RSA (как применить RSA-сертификат смотрите в разделе [Требования к сертификату](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/tls/tls));•шифрование с применением сертификатов ГОСТ (раздел в подготовке).Выбор того или иного метода шифрования канала определяется критичностью данных: + +•если персональные данные не передаются, то TLS RSA будет самым простым, дешёвым и гибким инструментом интеграции;•если персональные данные передаются, то обязательно использование сертификата ГОСТ. Партнёр API может выбирать, что использовать - TLS ГОСТ или вариант с ФПСУ ГОСТ. diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/check-list.md b/_docs/alfabank/payin_and_kyc/Общая_информация/check-list.md new file mode 100644 index 0000000..fd2f5cb --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/check-list.md @@ -0,0 +1,32 @@ +## Чек-лист готовности к тестовой интеграции + +1. **Заключите соглашение и договор** + Заключите соглашение о конфиденциальности и неразглашении информации, договор на информационно-технологическое взаимодействие с банком и подпишите приложения к нему. Подробнее в шаге 1 [инструкции по подключению](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/instruction/instruction). + +2. **Получите тестовые client_id и scope** + Подробнее в шаге 2 [инструкции по подготовке к работе с песочницей](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/instruction/instruction). + +3. **Установите тестовый TLS-сертификат, сертификаты Минцифры и проверьте доступ до Swagger UI** + Подробнее в шагах 3-5 [инструкции по подготовке к работе с песочницей](https://developers.alfabank.ru/products/alfa-api/documentation/articles/sandbox/sandbox). + +4. **Получите тестовый client_secret** + Подробнее [на странице Client secret](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret). + +5. **Реализуйте и протестируйте интеграцию Alfa ID и Alfa API в песочнице** + + +## Чек-лист готовности к промышленной интеграции + +1. **Выполните все пункты из подраздела «Проверьте готовность к тестовой интеграции»** + + +2. **Создайте интеграцию в проме на Портале разработчика** + Подробнее [на странице Создание интеграции в проме](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/prod/prod) + +3. **Выпустите TLS-сертификат** + Подробнее [на странице TLS-сертификат](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/tls/tls) + +4. **Получите client_secret** + Подробнее [на странице Client secret](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) + +5. **Начните использовать Alfa ID и Alfa API** diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/introduction.md b/_docs/alfabank/payin_and_kyc/Общая_информация/introduction.md new file mode 100644 index 0000000..fea4849 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/introduction.md @@ -0,0 +1,40 @@ +`B2B` `B2C` `H2H` + +# Введение + +Добро пожаловать в документацию для разработчиков! + +Мы рады приветствовать вас на нашем портале, где вы найдёте исчерпывающую информацию об Alfa API и все необходимые инструменты для успешного и безопасного использования наших услуг. + +Перед началом работы рекомендуем внимательно ознакомиться с нашей документацией, которая содержит всю необходимую информацию для успешной интеграции. + +[Подключение к Alfa API](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/connection) + +[Песочница](https://developers.alfabank.ru/products/alfa-api/documentation/articles/sandbox/sandbox) + +## Преимущества + +Alfa API предоставляет ряд преимуществ для наших клиентов и партнёров, включая: + +- быстрый и безопасный доступ к нашим банковским услугам; +- простоту интеграции с вашими приложениями и сервисами; +- возможность управления счетами, переводами и другими банковскими операциями; +- доступ к актуальным данным о состоянии счетов и истории операций. + +## Типы интеграций + +`B2B` `B2C` + +**Партнёрские сервисы** — при данном типе интеграции предоставляется возможность выполнять операции по другим организациям (при наличии от них согласия) для предоставления им услуг. В рамках этой интеграции можно выполнять операции по юридическим лицам (другие компании), взаимодействие бизнеса с бизнесом. А также можно выполнять операции, где конечным потребителем услуг является физическое лицо. + +`H2H` + +**H2H-интеграции (Host-to-Host)** — при данном типе интеграции предоставляется возможность встроить банковские продукты в ERP-систему для выполнения операций по своей организации. + +**Холдинги** — при данном типе интеграции предоставляется возможность для головной организации выполнять казначейские функции по своим дочерним компаниям. + +Поможем выбрать интеграцию за 15 секунд — **[Пройдите опрос]** + +При создании Alfa API и Alfa ID использовались спецификации: [OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc6749); [OIDC 1.0](https://openid.net/specs/openid-connect-core-1_0.html); [формат JSON](https://www.json.org/json-en.html); RESTful архитектура и синхронный обмен данными. + +Обновления по релизам публикуются в [Телеграм-канал](https://t.me/AlfaAPI) diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/pagination.md b/_docs/alfabank/payin_and_kyc/Общая_информация/pagination.md new file mode 100644 index 0000000..c41c898 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/pagination.md @@ -0,0 +1,85 @@ +[](https://developers.alfabank.ru/) / Общая информация / Пагинация + +`B2B` `B2C` `H2H` + +# Пагинация + +--- + +Пагинация - разделение ответа на несколько страниц. Механизм пагинации может быть использован в REST-запросах GET. + +## Параметры запроса + +**Пример запроса** +```bash +1curl -X GET '{host}/claims?limit=5&offset=5' + -H 'Content-Type: application/json' +``` + +### QUERY + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **limit** | `NUMBER` _(optional)_ | Количество объектов на одной странице. Значение по умолчанию: 1000. Максимальное значение: 1000 | +| **offset** | `NUMBER` _(optional)_ | Количество объектов в списке, которые необходимо пропустить. Значение по умолчанию: 0 | + +Количество объектов на одной странице. Значение по умолчанию: 1000. Максимальное значение: 1000 + +Количество объектов в списке, которые необходимо пропустить. Значение по умолчанию: 0 + +## Параметры ответа + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **limit** | `NUMBER` _(optional)_ | Количество объектов на одной странице | +| **offset** | `NUMBER` _(optional)_ | Количество объектов в списке, которые необходимо пропустить | +| **totalCount** | `NUMBER` _(optional)_ | Общее количество записей | + +#### Ответ: 200 OK + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **limit** | `NUMBER` _(optional)_ | Количество объектов на одной странице | +| **offset** | `NUMBER` _(optional)_ | Количество объектов в списке, которые необходимо пропустить | +| **totalCount** | `NUMBER` _(optional)_ | Общее количество записей | + + + +Количество объектов на одной странице + +Количество объектов в списке, которые необходимо пропустить + +Общее количество записей + + + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | `STRING` **(required)** | Код ошибки. Принимает возможные значения: invalid_request - неверные входные параметры запроса | +| **error_description** | `STRING` _(optional)_ | Описание ошибки | + +#### Ответ: 400 Bad Request + +```json +invalid_request +``` + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | `STRING` **(required)** | Код ошибки. Принимает возможные значения: invalid_request - неверные входные параметры запроса | +| **error_description** | `STRING` _(optional)_ | Описание ошибки | + +Код ошибки. Принимает возможные значения: invalid_request - неверные входные параметры запроса + +Описание ошибки + +## Алгоритм работы пагинации + +Пример 1: Если клиент запрашивает limit = 100, offset = 0, то клиенту вернётся с 1-ой по 100-ую запись. + +Пример 2: Если клиент запрашивает limit = 100, offset = 1000, то клиенту вернётся с 1001-ой по 1100-ую запись. + +Сортировка в пагинации происходит следующим образом: вверху списка возвращаются новые записи, внизу - старые записи. + +--- +[Версионирование](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/version/version) | [Термины и определения](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/terms/terms) diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/scopes.md b/_docs/alfabank/payin_and_kyc/Общая_информация/scopes.md new file mode 100644 index 0000000..038e1b6 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/scopes.md @@ -0,0 +1,49 @@ +* / Общая информация / Scopes (области применения)* + +`B2B` `B2C` `H2H` + +# Scopes (области применения) + +| SCOPE | DESCRIPTION | RESOURSES | +| --- | --- | --- | +| transactions | Выписки по счетам юрлиц | `GET /jp/v1/statement/transactions`
`GET /jp/v2/accounts/{accountNumber}/transactions/1C`
`GET /jp/v1/accounts/{accountNumber}/transactions/MT940`
`GET /jp/v1/correspondent-accounts/{accountNumber}/transactions`
`GET /jp/v1/statement/summary`
`POST /jp/v1/accounts/{accountNumber}/transactions/files/requests`
`GET /jp/v1/accounts/transactions/files/requests/{requestId}` | +| escrow | Эскроу-счета 214-ФЗ. Резервирование | `GET /build-projects`
`POST /escrow-orders`
`GET /jp/v1/escrow-orders/{referenceID}`
`GET /jp/v1/escrow-orders`
`PATCH /escrow-orders/{referenceID}/execute`
`DELETE /escrow-orders/{referenceID}`
`POST /jp/v1/escrow-orders/{referenceID}/cancel`
`POST /jp/v1/escrow-orders-full` | +| escrow-reports | Эскроу-счета 214-ФЗ. Формирование отчётов | `GET /jp/v1/escrow-reports/developers/build-projects`
`POST /jp/v1/escrow-reports` | +| customer | Профиль организации | `GET /jp/v2/customer-info` | +| payment | Платёжные поручения | `POST /jp/v2/payments`
`GET /jp/v2/payments/{externalId}/state`
`GET /jp/v1/payments/{externalId}`
`GET /jp/v1/payments/{externalId}/print-form`
`GET /jp/v1/payments/{externalId}/print-form/download`
`PATCH /jp/v2/payments/{externalId}/state` | +| as-operation-with-selfemployed | Добавление самозанятых, получение справочных данных | `POST /semp/v1/agreement-pages`
`POST /semp/v1/selfemployed/registries/add-selfemployed`
`GET /semp/v1/selfemployed/registries/add-selfemployed/{requestId}`
`GET /semp/v1/dictionary/activities`
`GET /semp/v1/dictionary/regions`
`GET /semp/v1/selfemployed/lists`
`GET /semp/v1/selfemployed/{vatin}`
`PUT /semp/v1/selfemployed/{vatin}` | +| as-selfemployed-fts-status | Статус самозанятого | `POST /semp/v1/selfemployed/taxpayer-statuses`
`GET /semp/v1/selfemployed/taxpayer-statuses/{requestId}` | +| as-accrual-and-debt | Налоговые начисления, задолженности и пени самозанятого | `POST /semp/v1/selfemployed/accruals-and-debts`
`GET /semp/v1/selfemployed/accruals-and-debts/{requestId}`
`POST /semp/v1/selfemployed/payment-documents`
`GET /semp/v1/selfemployed/payment-documents/{requestId}`
`POST /semp/v1/selfemployed/income-for-period`
`GET /semp/v1/selfemployed/income-for-period/{requestId}`
`POST /semp/v1/selfemployed/income`
`GET /semp/v1/selfemployed/income/{requestId}`
`POST /semp/v1/selfemployed/taxpayer-account-info`
`GET /semp/v1/selfemployed/taxpayer-account-info/{requestId}` | +| as-receipt-and-payout | Проведение выплат и формирование чеков, список банков-участников СБП | `POST /semp/v1/payouts/registries/receipts-and-payouts`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/cancel-receipts`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-receipt | Декларация доходов, аннулирование чеков | `POST /semp/v1/payouts/registries/receipts`
`POST /semp/v1/payouts/registries/cancel-receipts`
`GET /semp/v1/payouts/registries/cancel-receipts/{requestId}`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-payout-with-check-status | Проведение выплат самозанятым, список банков-участников СБП | `POST /semp/v1/payouts/registries/with-selfemployed-check-status`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-payout | Осуществление выплат самозанятым | `POST /semp/v1/payouts/registries/payouts`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| sbp_terminals_reg | Приём оплаты через СБП | `GET /jp/v1/legal`
`GET /jp/v1/merchants/{merchantId}`
`POST /jp/v1/terminals` | +| loan-applications | Кредиты | `POST /smart-loans/jp/v1/loan-applications`
`POST /loan-applications`
`GET /smart-loans/jp/v1/loan-applications/{dealId}/status` | +| signature | Электронная подпись | `GET /jp/v3/signature/dn`
`GET /jp/v3/signature/dn/file`
`POST /jp/v3/signature/rsa-certificates/requests/issue`
`POST /jp/v3/signature/requests/{id}/operations`
`PUT /jp/v3/signature/requests/operations/{id}`
`GET /jp/v3/signature/requests/{id}`
`GET /jp/v3/signature/rsa-certificates/{id}`
`POST /jp/v3/signature/rsa-certificates/{id}/requests/activation`
`PUT /jp/v3/signature/sign-settings`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/switch`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/reissue`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/revocation`
`POST /jp/v3/signature/qes/requests`
`POST /jp/v3/signature/qes/requests/{Id}`
`PATCH /jp/v3/signature/qes/requests/{Id}`
`POST /jp/v3/signature/powers-of-attorney/requests`
`GET /jp/v3/signature/powers-of-attorney/requests/{id}/status`
`GET /jp/v3/signature/powers-of-attorney/requests/{id}` | +| accounts | Счета | `GET /pp/v1/accounts`
`GET /pp/v1/accounts/{accountNumber}`
`GET /pp/v1/accounts/{accountNumber}/requisites`
`GET /jp/open-banking/v1.3/accounts`
`GET /jp/open-banking/v1.3/accounts/{accountId}/statements`
`POST /jp/open-banking/v1.3/statements`
`GET /jp/open-banking/v1.3/statements/{statementId}` | +| cards | Карты | `GET /pp/v1/cards`
`GET /pp/v1/cards/{cardId}/tariffs`
`GET /pp/v1/cards/{cardId}/subscriptions` | +| card-sec-actions | Тарифы и операции по карте | `GET /pp/v1/cards/{cardId}/actions`
`POST /pp/v1/cards/{cardId}/actions`
`PUT /pp/v1/cards/{cardId}/actions` | +| operations-history | Истории операций | `GET /pp/v1/operations`
`GET /pp/v1/operations/{id}` | +| reports-downloading | Получение документов | `GET /pp/v1/reports`
`GET /pp/v1/reports/{reportId}/body` | +| debit-statements | Выписки по счёту | `POST /pp/v1/reports/type/account`
`POST /pp/v1/reports/type/account/balance/eng`
`POST /pp/v1/reports/type/account/balance/rus` | +| credit-statements | Справки по кредитам | `POST /pp/v1/reports/type/credit/closed`
`POST /pp/v1/reports/type/credit/info`
`POST /pp/v1/reports/type/credit/statement` | +| deposit-statements | Справка по депозиту | `POST /pp/v1/reports/type/deposit` | +| limits-control | Лимиты по операциям | `GET /pp/v1/limits/general`
`GET /pp/v1/cards/{cardId}/user-limits`
`POST /pp/v1/cards/{cardId}/user-limits`
`DELETE /pp/v1/cards/{cardId}/user-limits/{limitId}` | +| loyalty | Программа лояльности | `POST /pp/v1/bonus-accounts-transactions`
`GET /pp/v1/bonus-accounts`
`GET /pp/v1/bonus-accounts/{accountNumber}` | +| b2c_sbp_payments | Платежи через СБП | `POST /b2cpay/jp/v1/payments`
`GET /b2cpay/jp/v1/payments`
`GET /b2cpay/jp/v1/payments/packages/{packageId}`
`POST /b2cpay/jp/v1/clients/checks`
`GET /b2cpay/jp/v1/clients/checks/{checkId}`
`GET /b2cpay/jp/v1/clients/info`
`GET /b2cpay/jp/v1/banks`
`GET /b2cpay/jp/v1/payments/download/{transactionId}` | +| credit | Кредитные предложения | `GET /pp/v1/credit-offers` | +| c2b-sbp | Оплата покупок через СБП | `POST /sbp/jp/v1/qrcs`
`POST /sbp/jp/v1/subscriptions`
`GET /sbp/jp/v1/qrc-status`
`POST /sbp/jp/v1/petitions`
`POST /sbp/jp/v1/terminals/{termNo}/cash-qrcs`
`POST /sbp/jp/v1/terminals/{termNo}/cash-qrcs/{qrcId}/activation`
`DELETE /sbp/jp/v1/terminals/{termNo}/cash-qrcs/{qrcId}/activation`
`POST /sbp/jp/v1/refund`
`GET /sbp/jp/v1/refund/status` | +| b2b-sbp | Операции СБП для юрлиц | `POST /sbp/jp/v1/payment-urls/one-time-use`
`POST /sbp/jp/v1/payment-urls/reusable`
`GET /sbp/jp/v1/payment-urls`
`GET /sbp/jp/v1/payment-urls/{qrcId}/data`
`GET /sbp/jp/v1/incoming-payments`
`POST /sbp/jp/v1/outgoing-payments/one-pay`
`GET /sbp/jp/v1/outgoing-payments`
`GET /sbp/jp/v1/outgoing-payments/{outgoingPaymentId}/status`
`POST /sbp/jp/v1/payment-urls/batch`
`GET /sbp/jp/v1/payment-urls/batch/{batchId}`
`PATCH /sbp/jp/v1/payment-urls` | +| digital-tariff | Дебетовая анкета | `POST /pp/v1/debit-cards/forms`
`POST /pp/v1/debit-cards/forms/{formId}/verification-sms`
`POST /pp/v1/debit-cards/forms/{formId}/resending-sms`
`POST /pp/v1/debit-cards/forms/{formId}/verification-passport` | +| plastic-delivery | Доставка дебетовой карты | `POST /pp/v1/debit-cards/forms/{formId}/verification-sms`
`POST /pp/v1/debit-cards/forms/{formId}/resending-sms`
`GET /pp/v1/debit-cards/forms/{formId}/draft`
`GET /pp/v1/debit-cards/forms/{formId}/delivery-type`
`GET /pp/v1/debit-cards/forms/{formId}/time-slots`
`POST /pp/v1/debit-cards/forms/{formId}/time-slots`
`POST /pp/v1/debit-cards/forms/{formId}/confirmation` | +| dfa | Цифровые финансовые активы (ЦФА) | `GET /dfa/gd/v1/dfa-profile/initial-placement-list` | +| salary-project | Зарплатный проект | `POST /jp/v1/salary-project/accounts/applications`
`GET /jp/v1/salary-project/accounts/applications/{applicationId}`
`POST /jp/v1/salary-project/payroll/applications`
`GET /jp/v1/salary-project/payroll/applications/{applicationId}` | +| loyalty-program | Получение бонусных номеров | `GET /pp/v1/bonus-numbers` | +| payment-registries | Реестры рублёвых платежей | `POST /jp/v2/payments/registries`
`GET /jp/v2/payments/registries/{registryId}` | +| invoices | Выставление счёта клиенту | `POST /jp/v1/payments/from-invoice`
`POST /jp/v2/payments/from-invoice-budget` | +| factoring | Факторинг | `GET /aff/jp/v1/creditors/compliance`
`POST /aff/jp/v1/payments`
`POST /aff/jp/v1/registers`
`POST /aff/jp/v1/registers/sign`
`GET /aff/jp/v1/payments/{paymentId}`
`GET /aff/jp/v1/registers/{registerId}`
`GET /aff/jp/v1/registers/{registerId}/documents` | +| beneficiaries | Информация о номинальных счетах и их контрагенты | `GET /na/jp/v1/nominal-accounts`
`GET /na/jp/v1/beneficiaries/requests/{requestId}/status`
`POST /na/jp/v1/beneficiaries`
`GET /na/jp/v1/beneficiaries`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}`
`PUT /na/jp/v1/beneficiaries/{beneficiaryId}`
`POST /na/jp/v1/beneficiaries/{beneficiaryId}/scoring`
`POST /na/jp/v1/beneficiaries/{beneficiaryId}/requisites`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/requisites`
`PATCH /na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/balance`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/transactions`
`POST /na/jp/v1/universal-recipients`
`GET /na/jp/v1/universal-recipients`
`GET/na/jp/v1/universal-recipients/{universalRecipientId}`
`POST /na/jp/v1/universal-recipients/{universalRecipientId}/requisites`
`GET /na/jp/v1/universal-recipients/{universalRecipientId}/requisites`
`PATCH /na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}` | +| deals | Безопасные сделки | `POST /na/jp/v1/deals`
`GET /na/jp/v1/deals`
`GET /na/jp/v1/deals/{dealId}`
`PATCH /na/jp/v1/deals/{dealId}/is-valid`
`GET /na/jp/v1/deals/{dealId}/payoffs`
`PATCH /na/jp/v1/deals/action`
`POST /na/jp/v1/deals/steps`
`GET /na/jp/v1/deals/{dealId}/requests/{requestId}/status`
`GET /na/jp/v1/deals/{dealId}/steps`
`GET /na/jp/v1/deals/{dealId}/steps/{stepId}`
`PATCH /na/jp/v1/deals/steps/contractors`
`GET /na/jp/v1/deals/{dealId}/steps/{stepId}/contractors` | +| beneficiary-payments | Идентификация пополнений номинального счёта и выплаты с него | `GET /na/jp/v1/unidentified-transactions`
`POST /na/jp/v1/unidentified-transactions/{id}/identify`
`GET /na/jp/v1/unidentified-transactions/{id}/identify/{identifyId}`
`POST /na/jp/v1/unidentified-transactions/{id}/refunds`
`GET /na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}`
`POST /na/jp/v1/payoffs`
`GET /na/jp/v1/payoffs/{payoffId}/status`
`PATCH /na/jp/v1/payoffs/{payoffId}/accept`
`GET /na/jp/v1/payoffs/{payoffId}`
`POST /na/jp/v1/tax-refund`
`GET /na/jp/v1/tax-refund/{taxRefundId}/status`
`PATCH /na/jp/v1/tax-refund/{taxRefundId}/accept` | + diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/terms_and_definitions.md b/_docs/alfabank/payin_and_kyc/Общая_информация/terms_and_definitions.md new file mode 100644 index 0000000..8d2daed --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/terms_and_definitions.md @@ -0,0 +1,65 @@ +[](https://developers.alfabank.ru/) / Общая информация / Термины и определения + +`B2B` `B2C` `H2H` + +# Термины и определения + +--- + +**Аутентификация** – процедура проверки данных пользователя, обратившегося для доступа к информационному ресурсу Партнёра API. + + + +**Банк** – Акционерное общество «Альфа-банк». + + + +**Грант** – вид сценария интеграции, такие как Authorization Code Flow или Client Credentials Flow. + + + +Партнёр API – клиент Банка, использующий канал Alfa API для проведения интеграции своей системы и системы/сервисов Банка. Для Партнёра API необходимо заключить Договор на информационно-технологическое взаимодействие в целях использования канала Alfa API. + + + +**Сервис** – набор методов API, доступ к которым от имени пользователя Вы можете получить. + + + +**Alfa API** – это канал предоставления банковских продуктов и услуг, а также инструмент их безопасной интеграции в бизнес-процессы Партнёров API. + + + +**Alfa ID** – единая учётная запись пользователя ЮЛ (юридического лица) / ФЛ (физического лица), используемая для регистрации и входа пользователей в продукты и сервисы Банка и Партнёров API. + + + +**Access token** – токен доступа, который формируется на основе согласия пользователя на взаимодействие от его имени Партнёра с Банком. + + + +**Claims** – набор данных пользователя, доступ к которым Вы можете получить. + + + +**Client ID** – уникальный идентификатор Партнёра API, который Вы получаете при регистрации. + + + +**Client secret** – секретный ключ партнёрского сервиса. + + + +**Redirect URI** – URL, на который сервер авторизации будет отправлять пользователя после успешной авторизации приложения и которому будет предоставляться код авторизации. Необходим при использовании типа гранта Authorization Code Flow. + + + +**Refresh token** - токен, который даёт возможность получить новый токен доступа взамен истекшего. + + + +**Scopes** – это общий набор операций и/или клэймов. + +--- +[Пагинация](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/pagination/pagination) | [Что это и для чего нужно](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/intro/intro) + diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/vensioning.md b/_docs/alfabank/payin_and_kyc/Общая_информация/vensioning.md new file mode 100644 index 0000000..ec04ce7 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/vensioning.md @@ -0,0 +1,29 @@ +# Версионирование + +Теги: `B2B` `B2C` `H2H` + +--- + +Версии методов/эндпоинтов обозначаются как `v1` , `v2` , `v3` и так далее. Это позволяет явно указать, какую версию API использует клиент. + +## Мажорные изменения + +Мажорные изменения подразумевают выпуск новой версии API. Они включают изменения, которые приводят к обратной несовместимости. + +Примеры мажорных изменений: + +•добавление обязательных параметров в запрос;•удаление обязательных параметров из запроса или ответа;•трансформация необязательных параметров в обязательные;•изменение типа параметра в запросе или ответе. +## Минорные изменения + +Минорные изменения не требуют выпуска новой версии API. Они не нарушают обратную совместимость. + +Примеры минорных изменений: + +•добавление новой функциональности без нарушения обратной совместимости;•исправление ошибок;•улучшение производительности;•дополнительные необязательные параметры в запросе или ответе. +## Поддержание старой версии + +Срок поддержки работы старой версии составляет от двух до шести месяцев. После этого срока Банк оставляет за собой право прекратить поддержку старой версии. При этом будет добавлено уведомление о прекращении поддержки старой версии эндпоинта. + +## Тестирование в песочнице + +Переход на новую версию обязательно должен включать тестирование в песочнице (тестовой среде). diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_android.md b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_android.md new file mode 100644 index 0000000..a083f21 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_android.md @@ -0,0 +1,60 @@ +*Общая информация / Сертификаты для Android* + +B2BB2CH2H# Сертификаты для Android + +Инструкция по установке сертификатов на телефон или планшет с системой Android. Для корректной работы нужно два сертификата - корневой и выпускающий. + +## Установка корневого сертификата + +1. **Скачайте корневой сертификат** +1.Скачайте корневой сертификат [Russian Trusted Root CA](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/russian_trusted_root_ca.cer).2.Перейдите в «Настройки».3.В поиске введите «Сертификат».4.Выберите «Сертификат CA».5.Если появится окно «Укажите название сертификата», введите «Russian Trusted Root CA».6.Выберите «VPN и приложения» и нажмите «ОК». +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android1.png) + +2. **Установите сертификат** +Если откроется предупреждение, нажмите «Всё равно установить» или «Установить в любом случае». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android2.png) + +3. **Введите пароль** +1.Введите код-пароль от устройства.2.Нажмите «Подтвердить».3.В загрузках выберите «Russian Trusted Root CA.cer». +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android3.png) + +4. **Сертификат установлен** +После установки в нижней части экрана появится уведомление «Сертификат ЦС установлен». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android4.png) + +## Установка выпускающего сертификата + +1. **Скачайте выпускающий сертификат** +1.Скачайте выпускающий сертификат [Russian Trusted Sub CA](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/russian_trusted_sub_ca.cer).2.Перейдите в «Настройки».3.В поиске введите «Сертификат».4.Выберите «Сертификат CA».5.В предупреждении нажмите «Всё равно установить» или «Установить в любом случае».6.Если появится окно «Укажите название сертификата», введите «Russian Trusted Sub CA».7.Выберите «VPN и приложения» и нажмите «ОК». +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android1.png) + +2. **Установите сертификат** +Если откроется предупреждение, нажмите «Всё равно установить» или «Установить в любом случае». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android3.png) + +3. **Введите пароль** +1.Введите код-пароль от устройства.2.Нажмите «Подтвердить».3.В загрузках выберите «Russian Trusted Sub CA.cer». +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android4.png) + +4. **Сертификат установлен** +После установки в нижней части экрана появится уведомление «Сертификат ЦС установлен». + +## Проверка установки сертификатов + +Проверьте, что сертификаты успешно установлены: + +1. **Перейдите в «Настройки»** + +2. **В поиске введите «Надёжные сертификаты» или «Надёжные учётные данные»** + +3. **Перейдите во вкладку «Пользователь»** +При успешной установке сертификатов в списке должно отобразиться два установленных сертификата Минцифры: «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/android/files/android5.png) + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +[Что это и для чего нужно](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/intro/intro)[Сертификаты для iOS](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/ios/ios) \ No newline at end of file diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_linux.md b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_linux.md new file mode 100644 index 0000000..ac9c0e8 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/for_linux.md @@ -0,0 +1,81 @@ +*Общая информация / Сертификаты для Linux* + +B2BB2CH2H# Сертификаты для Linux + +Инструкция по установке сертификатов для владельцев ноутбуков и компьютеров с операционной системой Linux. Для корректной работы нужно два сертификата - корневой и выпускающий. + +Процедура установки сертификатов зависит от используемого браузера. + +## Red Hat Enterprise Linux + +1. **Скачайте сертификаты** +Скачайте [корневой сертификат](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_root_ca_pem.crt) и [выпускающий сертификат](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_sub_ca_pem.crt). Загрузите сертификаты в папку «Downloads». + +2. **Установите сертификаты Удостоверяющего Центра Минцифры** +1. Нажмите на «Activities» -> «Terminal», чтобы открыть терминал. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux1.png) + +2. Убедитесь, что файлы сертификатов «russian_trusted_root_ca_pem.crt» и «russian_trusted_sub_ca_pem.crt» находятся в директории «Downloads». Для проверки перейдите в неё с помощью `cd` и вызовите команду `ls` для отображения списка файлов. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux2.png) + +3. Скопируйте корневой сертификат в каталог `/usr/share/pki/ca-trust-source/anchors/` . Выполните команду `sudo cp russian_trusted_root_ca_pem.crt /usr/share/pki/ca-trust-source/anchors` . + +4. Введите пароль суперпользователя. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux3.png) + +5. Cкопируйте в этот же каталог выпускающий сертификат. Выполните команду `sudo cp russian_trusted_sub_ca_pem.crt /usr/share/pki/ca-trust-source/anchors` . + +6. Обновите общесистемное хранилище сертификатов командой `sudo update-ca-trust` . + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux4.png) + +7. Проверьте хранилище доверенных сертификатов. Воспользуйтесь командой `trust list` . В конце списка должны появиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +## Mozilla Firefox + +1. **Скачайте сертификаты** +Скачайте [«корневой сертификат»](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_root_ca_pem.crt) и [«выпускающий сертификат»](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_sub_ca_pem.crt). Загрузите сертификаты в папку «Downloads». + +2. **Установите сертификаты Удостоверяющего Центра Минцифры** +1. Откройте браузер Firefox → перейдите в «Настройки» → в поиске введите «Сертификат» → выберите «Просмотр сертификатов…». + +2. В открывшемся окне «Управление сертификатами» нажмите на «Импортировать…». + +3. Перейдите в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_root_ca_pem.crt» → установите флажок «Доверять при идентификации веб-сайтов» → нажмите «ОК». + +4. В открывшемся окне «Управление сертификатами» нажмите «Импортировать». + +5. Вернитесь в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_sub_ca_pem.crt» → установите флажок «Доверять при идентификации веб-сайтов» → нажмите «ОК». + +6. Проверьте список сертификатов. Найдите в нём «The Ministry of Digital Development and Communications». Внутри должны находиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux5.png) + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +## Chromium + +1. **Скачайте сертификаты** +Скачайте [](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_root_ca_pem.crt) и [](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_sub_ca_pem.crt). Загрузите сертификаты в папку «Downloads». + +2. **Установите сертификаты Удостоверяющего Центра Минцифры** +1. Откройте браузер Chromium → перейдите в «Настройки» → в строке поиска введите «Сертификат» → нажмите на «Безопасность» в разделе «Конфиденциальность и безопасность» → выберите «Настроить сертификаты». + +2. Перейдите во вкладку «Центры сертификации» → выберите «Импорт». + +3. Перейдите в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_root_ca_pem.crt» → установите флажок «Доверять этому сертификату при идентификации сайтов» → нажмите «ОК». + +4. Во вкладке «Центры сертификации» снова выберите кнопку «Импорт» → дважды кликните по сертификату «russian_trusted_sub_ca_pem.crt» → установите флажок «Доверять этому сертификату при идентификации сайтов» → нажмите «ОК». + +5. Проверьте список сертификатов. Найдите «org-The Ministry of Digital Development and Communications» и раскройте список. Внутри должны находиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux6.png) + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +[Сертификаты для MacOS](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/macos/macos)[Как подключить](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/instruction/instruction) \ No newline at end of file diff --git a/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/what_it_is_and_what_it_is_for.md b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/what_it_is_and_what_it_is_for.md new file mode 100644 index 0000000..b7cb330 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Общая_информация/Сертификаты_Минцифры/what_it_is_and_what_it_is_for.md @@ -0,0 +1,22 @@ +[](https://developers.alfabank.ru/) / Общая информация / ... / Что это и для чего нужно + +`B2B` `B2C` `H2H` + +# Что это и для чего нужно + +--- + +Установка сертификата Министерства цифрового развития, связи и массовых коммуникаций Российской Федерации (Минцифры) необходима для подтверждения личности и безопасности пользователя при работе с определёнными типами данных и сервисов. + +Этот сертификат используется для шифрования данных, аутентификации пользователя и защиты от мошенничества и кибератак. + +Кроме того, он может потребоваться для доступа к некоторым государственным услугам и сервисам, связанным с электронной подписью и документооборотом. + +Для получения защищённого доступа ко всем сайтам и онлайн-сервисам используйте браузеры с поддержкой российских сертификатов: Яндекс Браузер или Атом. + +Альтернативный способ - установка корневого сертификата. Если Вы привыкли работать в других браузерах или возникли проблемы с работой сторонних программ, Вы можете установить корневой сертификат в операционную систему. + +Ответы на часто задаваемые вопросы можно посмотреть здесь. + +--- +[Термины и определения](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/terms/terms) | [Сертификаты для Android](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/android/android) diff --git a/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/check-webhook_intro.md b/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/check-webhook_intro.md new file mode 100644 index 0000000..bf1aaa4 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/check-webhook_intro.md @@ -0,0 +1,138 @@ +# Инструкция по тестированию + +**Теги:** `B2B` `B2C` `H2H` + +1. Отправьте письмо на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru) с указанием, что хотите подключить вебхуки. +2. На своей стороне реализуйте открытый [Партнёрский метод для получения вебхуков](/products/alfa-api/documentation/articles/webhooks/articles/partner-webhook/v1/partner-webhook). +3. Создайте вебхук в песочнице с помощью метода [«Создание вебхука»](/products/alfa-api/documentation/articles/webhooks/articles/create-webhook/v1/create-webhook). +4. Вызовите метод [«Проверка работы вебхука»](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/transactions/v1/transactions). + - В результате успешного запроса для `object = ul_transaction_default` создаются тестовые транзакции для следующих счетов: + - `40702810102300000001` + - `40702810402300000002` + - `40702810002300000003` + - `40702978902300000004` + - В результате успешного запроса для `object = jp_sbp_incoming_payments` будет создан тестовый платёж для счёта: + - `40702810100010000000` +5. После создания транзакций на ваш метод будет отправлен вебхук. Примеры форматов представлены ниже. + +### Пример формата вебхука для выписки + +```json +[ + { + "actionType": "update", + "eventTime": "2022-01-12T00:00:00", + "object": "ul_transaction_default", + "organizationId": "vvvvvv", + "data": { + "amount": { + "amount": 1.0, + "currencyName": "RUR" + }, + "amountRub": { + "amount": 1.0, + "currencyName": "RUR" + }, + "correspondingAccount": "30101810200000000593", + "direction": "CREDIT", + "documentDate": "2022-01-12", + "filial": "АО \"АЛЬФА-БАНК\" г Москва", + "number": "178", + "operationCode": "01", + "operationDate": "2022-01-12T00:00:00", + "paymentPurpose": "Перевод собственных средств. НДС не облагается.", + "priority": "5", + "revaln": null, + "uuid": "9084d309-b30b-5083-9a54-d4522472e11a", + "transactionId": "1220112MOCO#DS4001415", + "rurTransfer": { + "cartInfo": { + "documentCode": null, + "documentContent": null, + "documentDate": null, + "documentNumber": null, + "paymentNumber": null, + "restAmount": null + }, + "deliveryKind": "электронно", + "departmentalInfo": { + "uip": "1", + "drawerStatus101": "01", + "kbk": "18210102010011000110", + "oktmo": "12301000", + "reasonCode106": "ТП", + "taxPeriod107": "ГД.01.2022", + "docNumber108": "123", + "docDate109": "12.01.2022", + "paymentKind110": "1" + }, + "payeeAccount": "40702810301300000763", + "payeeBankBic": "044525593", + "payeeBankCorrAccount": "30101810200000000593", + "payeeBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payeeInn": "0140237176", + "payeeKpp": "770801001", + "payeeName": "Полное наименование Орг № 11329", + "payerAccount": "40702810701300000761", + "payerBankBic": "044525593", + "payerBankCorrAccount": "30101810200000000593", + "payerBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payerInn": "0140237176", + "payerKpp": "770801001", + "payerName": "Полное наименование Орг № 11329", + "payingCondition": null, + "purposeCode": "2", + "receiptDate": "2022-01-12", + "valueDate": "2022-01-12" + } + } + } +] +``` + +### Пример формата вебхука для входящих платежей + +```json +[ + { + "actionType": "update", + "eventTime": "2022-01-12T00:00:00", + "object": "jp_sbp_incoming_payments", + "organizationId": "vvvvvv", + "data": { + "qrcId": "AD1000038AQ1FG409KGACUQU5QRSH3FM", + "nspkTransactionId": "B467FC50C59A469A9898AB7B05EE3F07", + "amount": 1000000, + "taxAmount": 200000, + "paymentPurpose": "Оплата по договору №123456789 от 01.09.2001", + "payeeAccount": "40702810100010000000", + "payerAccount": null, + "currency": "RUR", + "timestamp": "2024-11-26T09:09:32Z", + "payerInfo": { + "name": "ИП Викулин", + "inn": "911006876365", + "bik": "044525593", + "accountType": "BBAN", + "bankName": "АО \"АЛЬФА-БАНК\"", + "bankCorrAccount": "30101810200000000593" + }, + "recipientInfo": { + "name": "OOO Ромашка", + "inn": "8110068763612", + "bik": "044625503", + "accountType": null, + "bankName": "БАНК", + "bankCorrAccount": "30101810200000000522" + } + } + } +] +``` + +--- + +**Навигация:** + +- ← [Начало работы в песочнице](/products/alfa-api/documentation/articles/sandbox/articles/intro/intro) +- [Проверка работы вебхука](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/transactions/v1/transactions) → diff --git a/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/checking_the_webhook_eg_transactions.md b/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/checking_the_webhook_eg_transactions.md new file mode 100644 index 0000000..a18eae4 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/check-webhook/checking_the_webhook_eg_transactions.md @@ -0,0 +1,101 @@ +# Проверка работы вебхука + +**Теги:** `B2B` `B2C` `H2H` + +### Эндпоинт для Песочницы + +`POST https://sandbox.alfabank.ru/api/v1/webhooks-events` + +### Scope + +`transactions` `b2b-sbp` + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **object** | string | required | Объект/сущность, на который партнёр API хочет подписаться. Возможные значения:
• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей | + +### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/v1/webhooks-events \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "object": "ul_transaction_default" + }' +``` + +--- + +## Параметры ответа + +### 201 Created + +Нет тела ответа. + +### 400 Bad Request + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :--------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +### 401 Unauthorized + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `invalid_token` — предоставленный токен просрочен, отозван, имеет неправильный формат или недействителен | +| **error_description** | string | optional | Описание ошибки | + +### 403 Forbidden + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `insufficient_scope` — у пользователя нет прав на использование запрашиваемого сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 404 Not Found + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `unknown_route` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +### 429 Too Many Requests + +Нет тела ответа. + +### 500 Internal Server Error + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 503 Service Unavailable + +Нет тела ответа. + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +## Навигация + +- ← [Инструкция по тестированию](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/intro/intro) +- [Тестирование электронной подписи](/products/alfa-api/documentation/articles/sandbox/articles/check-signature/check-signature) → diff --git a/_docs/alfabank/payin_and_kyc/Песочница/managing-certificates.md b/_docs/alfabank/payin_and_kyc/Песочница/managing-certificates.md new file mode 100644 index 0000000..44334af --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/managing-certificates.md @@ -0,0 +1,26 @@ +# Управление сертификатами для подписи и шифрования + +**Теги:** `B2B` `B2C` `H2H` + +### RSA + +Для тестирования подписи и шифрования сообщений с помощью RSA-сертификата Вам будет необходимо выпустить сертификат в УЦ Альфа-Банка с помощью сервиса [«Электронная подпись»](/products/alfa-api/documentation/articles/signature/signature). + +Первым шагом инструкции на выпуск RSA-сертификата выполняется запрос на сертификат. Для получения тестового сертификата на втором пункте с созданием закрытого ключа необходимо воспользоваться тестовым закрытым ключом [key-encrypted.zip](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/managing-certificates/files/sandbox_alfa_test_jwt_2026.zip) (пароль для архива уточняйте у персонального менеджера). + +Для проверки подписи необходимо использовать тестовый [сертификат](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/managing-certificates/files/sandbox_alfa_test_jwt_2026.cer) ключа проверки подписи. + +### ГОСТ + +Для тестирования подписи и шифрования сообщений с помощью ГОСТ-сертификата Вам будет необходимо выпустить сертификат в любом специализированном [государственном УЦ](https://digital.gov.ru/ru/activity/govservices/certification_authority/?utm_referrer=https%3a%2f%2fwww.google.com%2f). Далее сертификат необходимо загрузить в Банк с помощью метода [«Добавление сертификата»](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates), указав при этом в поле `type` тип этого сертификата. + +Для тестирования методов необходимо использовать URL [https://sandbox.alfabank.ru/api](https://sandbox.alfabank.ru/api). + +Для проверки подписи необходимо использовать тестовый сертификат ключа проверки подписи. Для получения сертификата напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +--- + +#### Навигация + +- ← [Тестирование электронной подписи](/products/alfa-api/documentation/articles/sandbox/articles/check-signature/check-signature) +- [Формат исходного сообщения JSON](/products/alfa-api/documentation/articles/sandbox/articles/signature/articles/jws/v1/jws) → diff --git a/_docs/alfabank/payin_and_kyc/Песочница/payments.md b/_docs/alfabank/payin_and_kyc/Песочница/payments.md new file mode 100644 index 0000000..e6ee837 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/payments.md @@ -0,0 +1,80 @@ +# Тестирование платёжных поручений + +**Теги:** `B2B` `H2H` + +Для тестирования метода [«Создание рублёвого платёжного поручения»](/products/alfa-api/documentation/articles/payments/articles/create/v2/create) в песочнице необходимо сгенерировать уникальный идентификатор для передачи в параметре `externalId`. + +При создании рублёвого платёжного поручения **с подписью** в параметре `certificateUuid` необходимо передать серийный номер RSA-сертификата: +`61000366d11e143acbc03a56d70001000366d1` + +### Значения БИК банка для тестирования + +Эти значения передаются в полях `payerBankBic` и `payeeBankBic`: + +- `040173745` +- `044525593` + +--- + +### Пример тестового запроса + +```bash +curl --location --request POST 'https://sandbox.alfabank.ru/api/jp/v2/payments' \ + --header 'Authorization: Bearer {access-token}' \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + --data-raw '{ + "amount": 1.00, + "date": "2022-10-11", + "deliveryKind": "электронно", + "departmentalInfo": { + "uip": "0", + "drawerStatus101": "01", + "kbk": "18210102010011000110", + "oktmo": "45902000", + "reasonCode106": "ТП", + "taxPeriod107": "МС.02.2022", + "docNumber108": "000000000000001", + "docDate109": "2022-05-25" + }, + "digestSignatures": [ + { + "base64Encoded": "HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w==", + "certificateUuid": "61000366d11e143acbc03a56d70001000366d1" + } + ], + "externalId": "22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6", + "number": "1047", + "operationCode": "01", + "payeeAccount": "40702810564564564531", + "payeeBankBic": "040173745", + "payeeBankCorrAccount": "30101810800000000745", + "payeeInn": "7723870785", + "payeeKpp": "553453453", + "payeeName": "Общество с ограниченной ответственностью \"Центр \"ИННОВАЦИЯ\"", + "payerAccount": "40702810102300000001", + "payerBankBic": "044525593", + "payerBankCorrAccount": "30101810200000000593", + "payerInn": "0453438040", + "payerKpp": "046773311", + "payerName": "Общество с ограниченной ответственностью \"Клиент\"", + "priority": "5", + "purpose": "Оплата заказа №1. НДС не облагается", + "urgencyCode": "NORMAL", + "vat": { + "rate": "0", + "type": "NO_VAT" + } +}' +``` + +--- + +### Навигация + +- ← [Формат исходного сообщения TXT](/products/alfa-api/documentation/articles/sandbox/articles/signature/articles/text/v1/text) +- [Для чего нужен SDK](/products/alfa-api/documentation/articles/sdk/articles/intro/intro) → + +--- + +_Примечание: Данный документ предназначен для работы в среде **Песочница**._ diff --git a/_docs/alfabank/payin_and_kyc/Песочница/sandbox_intro.md b/_docs/alfabank/payin_and_kyc/Песочница/sandbox_intro.md new file mode 100644 index 0000000..ebb8e86 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/sandbox_intro.md @@ -0,0 +1,142 @@ +# Начало работы в песочнице + +**Теги:** `B2B` `B2C` `H2H` + +**Песочница API** — это среда, которую партнёры API могут использовать для имитации промышленной среды и получения смоделированных ответов по всем API. + +Песочница позволяет пройти аутентификацию в Alfa ID и вызвать методы Alfa API в тестовом режиме, не воздействуя на реальные данные. + +> **Внимание** +> Обработка негативных сценариев (например, ошибки валидации или доступа) **в песочнице** может отличаться от обработки в промышленной среде и спецификации тестируемого метода. + +--- + +## Подготовка к работе в песочнице + +Для начала работы в песочнице пройдите следующие шаги: + +1. **Заключите договор о техническо-информационном взаимодействии** + Подробнее [на странице Подписание договора](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding). + +2. **Получите тестовый `client_id` и `scope`** + Получите `client_id` и доступные `scope` [на Портале разработчика](/products/alfa-api/documentation/articles/selfservice/articles/test/test). Также эти данные можно найти в письме, отправленном банком вам на почту после подписания договора. + +3. **Установите тестовый TLS-сертификат** + Для получения доступа к тестовой среде необходимо установить тестовый TLS-сертификат – [test_cert.zip](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/intro/files/test_cert.zip) – пароль для архива уточняйте у персонального менеджера. + + **Архив состоит из файлов:** + - `sandbox_cert_2026.cer` – сертификат для клиента (открытый ключ); + - `sandbox_key_2026.key` – закрытый ключ; + - `apica_2022_chain.cer` – цепочка сертификатов УЦ (содержит в себе `root_apica_2022.cer` и `sub_root_apica_2022.cer`); + - `root_apica_2022.cer` – корневой сертификат УЦ; + - `sub_root_apica_2022.cer` – промежуточный сертификат УЦ; + - `baas_swagger_2026.p12` – контейнер p12, содержащий вышеперечисленные файлы. + + Для доступа к Swagger UI можно использовать следующие комбинации (в зависимости от выбора Вашего ПО для работы с API): + - открытый ключ + закрытый ключ + цепочка сертификатов УЦ; + - открытый ключ + закрытый ключ + корневой сертификат УЦ + промежуточный сертификат УЦ; + - контейнер p12 (`baas_swagger_2026.p12`) – самый простой способ. + + **Важно!** Корневой сертификат УЦ необходимо добавить в доверенные сертификаты на своей стороне. + + Для вызова методов можно использовать стандартные программные средства для работы с API: Postman, SoapUI, JMeter, curl или использовать самописные программные средства или встроенные возможности ERP-системы. + +4. **Установите сертификаты Минцифры** + Для корректной работы песочницы необходимо установить [сертификаты Минцифры](/products/alfa-api/documentation/articles/specification/articles/certificate/articles/intro/intro). + +5. **Проверьте тестовый Swagger UI** + Тестовый Swagger UI находится по адресу [https://sandbox.alfabank.ru/swagger-ui/](https://sandbox.alfabank.ru/swagger-ui/) + +6. **Получите тестовый `client_secret`** + Подробнее [на странице Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret). + +--- + +## Особенности вызовов + +После выполнения указанных шагов вы можете приступать к тестированию запросов в песочнице. + +При использовании песочницы все вызовы API должны осуществляться с установкой mTLS-соединения. В зависимости от требований используемого вами клиента при отправке запросов вам может понадобиться сертификат и закрытый ключ. Рекомендуем ознакомиться с документацией используемого клиента. + +### Пример запроса (cURL) + +```bash +curl -X GET https://sandbox.alfabank.ru/api/v1/endpoint \ + -v --cert test_certificate.cer \ + --key test_key.key \ + --header 'accept: application/json' \ + --header 'content-type: application/json' +``` + +--- + +## Как сообщить об ошибке + +Отправьте письмо на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru), указав следующие данные: + +1. `client_id`. +2. Дата и время запроса с указанием часового пояса. +3. Метод и URI запроса. +4. Заголовки и тело запроса. +5. Полученная ошибка и заголовки ответа, включая `X-TraceId`. +6. IP-адрес, с которого был отправлен запрос. + +--- + +## Адреса для тестирования + +- **Получение кода авторизации:** [https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}](https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id=%7Bclient_id%7D&redirect_uri=%7Bredirect_uri%7D&scope=%7Bscope%7D&state=%7Bstate%7D) +- **Другие запросы в Alfa ID:** [https://sandbox.alfabank.ru/oidc](https://sandbox.alfabank.ru/oidc) +- **Запросы в Alfa API:** [https://sandbox.alfabank.ru/api](https://sandbox.alfabank.ru/api) + +--- + +## Счета для тестирования + +**Номера счетов:** + +- `40702810102300000001` +- `40702810402300000002` +- `40702810002300000003` +- `40702810002300000004` + +**Номер корреспондентского счёта:** + +- `30102810102300000593` + +--- + +## Рекомендации по тестированию Alfa ID ЮЛ (Юридические лица) + +Для прохождения процедуры аутентификации используйте тестовые данные: + +- **Login:** `SomeDifficultLogin` +- **Password:** `1qaz!QAZ` +- **One-Time Password (OTP):** `000000` + +Для подписания формы согласия используйте: + +- **One-Time Password:** `111111` + +Подробнее [в разделе Alfa ID](/products/alfa-api/documentation/articles/alfa-id/alfa-id). + +--- + +## Рекомендации по тестированию Alfa ID ФЛ (Физические лица) + +Для прохождения процедуры аутентификации используйте тестовые данные: + +- **Номер телефона:** `71111111111` +- **Login:** `SomeDifficultLogin` +- **Password:** `000000` +- **One-Time Password (OTP):** `000000` + +Для подписания формы согласия используйте: + +- **One-Time Password:** `000000` + +Подробнее [в разделе Alfa ID](/products/alfa-api/documentation/articles/alfa-id/alfa-id). + +--- + +[← API Key](/products/alfa-api/documentation/articles/api-key/api-key) | [Инструкция по тестированию вебхуков →](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/Песочница/signature-checking.md b/_docs/alfabank/payin_and_kyc/Песочница/signature-checking.md new file mode 100644 index 0000000..dfbcb00 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/signature-checking.md @@ -0,0 +1,40 @@ +# Тестирование электронной подписи + +**Теги:** `B2B` `H2H` + +Во втором шаге инструкции на [выпуск RSA-сертификата](/products/alfa-api/documentation/articles/signature/articles/intro/intro) выполняется запрос на сертификат. Для тестирования в песочнице необходимо использовать приложенный ниже `pkcs10Content` при вызове метода ["Заявка на выпуск RSA-сертификата"](/products/alfa-api/documentation/articles/signature/articles/issue-rsa/v1/issue-rsa). + +### Содержимое pkcs10Content (Certificate Request) + +```text +-----BEGIN CERTIFICATE REQUEST----- +MIIC/DCCAeQCAQAwgacxJTAjBgkqhkiG9w0BCQEWFlVzZXI1MDRAcG9jaHRvY2hr +YS5jb20xOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQ +nuSDQmNCz0L7RgNC10LLQuNGHMQswCQYDVQQGEwJSVTEbMBkGA1UEBAwS0JrRg9C0 +0YDRj9Cy0YbQtdCyMRcwFQYDVQQqDA7QldGA0LzQvtC70LDQuTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANGTN2bX/kaOHuuEfMiOKg1f8y3SY1AseVjQ +ceoHKdaSeLoUIscPgEsuDsbtF6ezsZqV7bwyRYuJK+kMprczDWKiQNxmZPOafiKG +5MKOcxysgX9LV+R8JhVoycfQqmSqfImQBcPZ6s9bqq6J8cs04FCzy+nhPYoFUs2l +X+ZrFfLF135fO4LlRxfj4dfIbHZ4NVogiezIteBE3SPTtEeXiYj2c7SyB0Z17gbQ +dTmtWIolrb5GTZ6SyjjcMZY3U2ZR+4eyn2l1MFt5F/K9Ke47zu4DYTF7zkitST11 +nr5gR64zjVZRtmrVqMU9iB7NmQ8/gS8YEsC3PTSECvqioSDHwNcCAwEAAaAPMA0G +CSqGSIb3DQEJDjEAMA0GCSqGSIb3DQEBCwUAA4IBAQBazGrfYMfeUdJ7ofbQ5lom +EsHO/cA312QUpyzFEsHbjYhy9OZTjiVXLfVExf8QrcRchi4/6IECp01S2Ed+nfMm +E/MtD3rtE2oBtH6FjA9APtZb9NZuiSYCzl7nL3rd0ui+F32Dy/JNkudktn64jsMH +YVt5u8Ik0dtxl0axa3E5RUkpJTTl7iIOWD+P8UkOOpa9EMPA2hrtrZvPr8xr60IS +d2t4vKFcHIdgdI2Qe5ATvaYfbccLGjxdWm05lXVuxRjpEOXjuhc5mRkEj06bPavD +9k7h/Tsz4Jb9gNKDZ3TEzfynQkDFFse8in6IDDkwPO21J6onTMd7KOP1gqMSYjrh +-----END CERTIFICATE REQUEST----- +``` + +### Данные для подтверждения + +Для шага с подписанием заявки с помощью кода из СМС использовать: +**One-Time Password: 11111111** + +--- + +#### Навигация + +- ← [Проверка работы вебхука](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/transactions/v1/transactions) +- [Управление сертификатами для подписи и шифрования](/products/alfa-api/documentation/articles/sandbox/articles/managing-certificates/managing-certificates) → diff --git a/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/jws_POST.md b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/jws_POST.md new file mode 100644 index 0000000..9568239 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/jws_POST.md @@ -0,0 +1,102 @@ +# Формат исходного сообщения JSON + +**Метод:** `POST` +**Эндпоинт (Песочница):** `https://sandbox.alfabank.ru/api/signature-encryption-tests/json` + +--- + +### Описание + +С помощью данного метода можно протестировать подпись и шифрование сообщения в формате JSON с использованием ГОСТ- или RSA-сертификата. + +- Процесс формирования и подписания сообщения с использованием RSA-сертификата описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-rsa/json-rsa). +- Процесс формирования и шифрования сообщения RSA описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/json-rsa/json-rsa). +- Подписание запроса и дешифрование ответа происходит с использованием закрытого ключа сертификата. Для тестирования необходимо использовать тестовый [закрытый ключ](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/signature/articles/jws/v1/files/sandbox_alfa_test_jwt_2026.zip) (пароль уточняйте у персонального менеджера). +- Процесс формирования и подписания сообщения с использованием ГОСТ-сертификата описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-gost/json-gost). +- Процесс формирования и шифрования сообщения ГОСТ описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/json-gost/json-gost). + +> **Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке Вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------------- | :----- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/jose | +| **Content-Type** | string | required | application/jose | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты канала для запроса. Значения: `NO` (без защиты), `SIGNATURE` (проверка подписи), `ENCRYPTION` (дешифрование и проверка подписи). | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты канала для ответа. Значения: `NO` (без защиты), `SIGNATURE` (подписание ответа), `ENCRYPTION` (подписание и шифрование ответа). | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------ | :----- | :------------- | :-------------------------------- | +| (root) | string | required | Тело подписи в виде base64-строки | + +--- + +### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/json \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/jose' \ + -H 'Content-Type: application/jose' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### 201 Created + +| Атрибут | Тип | Обязательность | Описание | +| :------ | :----- | :------------- | :---------- | +| (root) | string | optional | Тело ответа | + +#### 400 Bad Request + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------- | +| **error** | string | required | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +#### 401 Unauthorized + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------------------------ | +| **error** | string | required | Код ошибки: `invalid_token` — токен просрочен, отозван или недействителен | +| **error_description** | string | optional | Описание ошибки | + +#### 404 Not Found + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :---------------------------------------------------------------- | +| **error** | string | required | Код ошибки: `unknown_endpoint` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +#### 500 Internal Server Error + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------- | +| **error** | string | required | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +--- + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации._ + +--- + +**Навигация:** + +- [← Управление сертификатами для подписи и шифрования](/products/alfa-api/documentation/articles/sandbox/articles/managing-certificates/managing-certificates) +- [Формат исходного сообщения XML →](/products/alfa-api/documentation/articles/sandbox/articles/signature/articles/xmldsig/v1/xmldsig) diff --git a/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/text_POST.md b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/text_POST.md new file mode 100644 index 0000000..ae734af --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/text_POST.md @@ -0,0 +1,72 @@ +Вот преобразованный в Markdown формат документации для метода тестирования подписи и шифрования TXT-сообщений. + +--- + +# Формат исходного сообщения TXT + +Метод позволяет протестировать подпись и шифрование сообщения в формате TXT с использованием ГОСТ- или RSA-сертификата. + +### Эндпоинт (Песочница) +`POST https://sandbox.alfabank.ru/api/signature-encryption-tests/text` + +--- + +### Описание процесса +* **RSA-сертификат:** Процесс формирования и подписания описан [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/text-rsa/text-rsa), а шифрования — [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/text-rsa/text-rsa). +* **ГОСТ-сертификат:** Процесс формирования и подписания описан [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/text-gost/text-gost), а шифрования — [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/text-gost/text-gost). +* **Тестирование:** Подписание запроса и дешифрование ответа происходит с использованием закрытого ключа. Для тестов используйте [закрытый ключ](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/signature/articles/text/v1/files/sandbox_alfa_test_jwt_2026.zip) (пароль уточняйте у персонального менеджера). + +> **⚠️ Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения настроек или их изменения напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru), указав способ защиты (подпись или подпись с шифрованием) и алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | text/plain | +| **Content-Type** | string | required | text/plain | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты запроса. Значения: `NO` (без защиты), `SIGNATURE` (подпись), `ENCRYPTION` (дешифрование и подпись). | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты ответа. Значения: `NO` (без защиты), `SIGNATURE` (подпись), `ENCRYPTION` (подпись и шифрование). | + +#### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| — | string | required | Тело подписи в виде base64-строки | + +#### Пример запроса +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/text \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: text/plain' \ + -H 'Content-Type: text/plain' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### 201 Created +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **responseTextFiled** | string | optional | Тело ответа | + +**Пример ответа:** +```text +responseTextFiled:responseTextValue +``` + +#### Ошибки (400, 401, 404, 500) +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки (например, `invalid_request`, `invalid_token`, `unknown_endpoint`, `internal_error`) | +| **error_description** | string | optional | Детальное описание ошибки | + +--- +*Примечание: Значения параметров ошибок могут изменяться. Рекомендуется предусмотреть стандартную обработку ошибок.* diff --git a/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/xmldsig_POST.md b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/xmldsig_POST.md new file mode 100644 index 0000000..a50fa4f --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Песочница/signature-encryption-tests/xmldsig_POST.md @@ -0,0 +1,133 @@ +# Формат исходного сообщения XML + +**Теги:** `B2B` `B2C` `H2H` + +### Эндпоинт для тестирования (Песочница) + +`POST https://sandbox.alfabank.ru/api/signature-encryption-tests/xml` + +--- + +### Описание + +С помощью данного метода можно протестировать подпись и шифрование сообщения в формате XML с использованием RSA-сертификата. + +Процесс формирования и подписания сообщения с использованием RSA-сертификата описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/xml-rsa/xml-rsa), а процесс формирования и шифрования сообщения описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/xml-rsa/xml-rsa). Подписание запроса и дешифрование ответа происходит с использованием закрытого ключа сертификата. Для тестирования необходимо использовать тестовый [закрытый ключ](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/signature/articles/xmldsig/v1/files/sandbox_alfa_test_jwt_2026.zip) (пароль уточняйте у персонального менеджера). + +Процесс формирования и подписания сообщения с использованием ГОСТ-сертификата описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/xml-gost/xml-gost), а процесс формирования и шифрования сообщения описан [здесь](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/xml-gost/xml-gost). + +> **Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------------- | :----- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/xml | +| **Content-Type** | string | required | application/xml | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты канала для запроса. Значения: `NO` — без защиты; `SIGNATURE` — проверка подписи; `ENCRYPTION` — дешифрование и проверка подписи. | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты канала для ответа. Значения: `NO` — без защиты; `SIGNATURE` — подписание ответа; `ENCRYPTION` — подписание и шифрование. | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :----- | :------------- | :-------------------------------- | +| (тело запроса) | string | required | Тело подписи в виде base64-строки | + +#### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/xml \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/xml' \ + -H 'Content-Type: application/xml' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### Успешный ответ (201 Created) + +| Атрибут | Тип | Описание | +| :---------------------------- | :----- | :---------------------------------------------------------------- | +| **ds:Signature** | string | Корневой элемент XML Signature | +| **ds:SignedInfo** | string | Содержит информацию об алгоритме канонизации, подписи и дайджесте | +| **ds:CanonicalizationMethod** | string | Алгоритм канонизации (атрибут `Algorithm`) | +| **ds:SignatureMethod** | string | Алгоритм подписи (атрибут `Algorithm`) | +| **ds:DigestMethod** | string | Алгоритм дайджеста (атрибут `Algorithm`) | +| **ds:SignatureValue** | string | Значение тела подписи в кодировке base64 | +| **ds:KeyInfo** | string | Информация о ключах и сертификатах для проверки подписи | +| **ds:X509Data** | string | Информация о сертификатах | +| **ds:X509Certificate** | string | Сертификат, которым подписано тело, в base64 | + +#### Пример ответа 201 + +```xml + + + XmlElementValue2 + + H6jGW+bKLwvQ9xxbhZ6jNYRHtupT4aJ4jjlLh4W8svK0w5G7ZXf4OxqRR0t2l6aYOpNBdN2Q0+2T +1LXyadtnz7XJ7QYXNXrnWNcq7mOxM5Lj5bBQa2JPZSiMkp1lsnAV/LFDAJ+Uhruj3mFQxjiFpJLR +W/vRJzmRv925xXWopb94PFvP9mjtAwPXtBGEL5rqJICabzVo8+1BfPwFF5+8sqYzT74mmJIQmeFm +FiYVMNive5lRxlt7nXEgS4iENF1dXq5+prCPloms8hIX6I4HQo3Jn+G37Os57nv8g61gk4jnu2OK +bOsZasIzXSLVG2GrCbDQ+HFjWs3Fgg4JOkULfw== + + + + + + xgVcc1UZhuWRp4/8K0OAVLuQUhySUtJg7mYo78Od+WWidnIZr2XZUvPqwxOpFwRY + + + + + + + + + + + + + MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCG... (урезано для краткости) + + + + XmlElementValue1 + +``` + +--- + +### Ошибки + +| Код | Описание | Возможные значения `Error` | +| :------ | :-------------------- | :------------------------------------------------------------ | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | + +#### Пример ошибки 400 + +```xml + + + invalid_request + Authorization header is not present in request headers + +``` + +--- + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации._ diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_id.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_id.md new file mode 100644 index 0000000..f2063cc --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_id.md @@ -0,0 +1,32 @@ +# Client ID + +**B2B** **B2C** **H2H** + +Тестовый `client_id` и доступный для использования `scope` будут отправлены на почту, указанную [при подписании договора](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding), сразу после его подписания. Также тестовые учётные данные будут доступны [на Портале разработчика](/products/alfa-api/documentation/articles/selfservice/articles/intro/intro). + +Для получения промышленного `client_id` необходимо [создать интеграцию в проме](/products/alfa-api/documentation/articles/selfservice/articles/prod/prod) на Портале разработчика. `client_id` будет указан в карточке интеграции. + +У вас может быть несколько `client_id` в случаях, если: + +- вы интегрируете Alfa API / Alfa ID в свой сервис, используя разные точки входа для пользователей-физических лиц и пользователей-юридических лиц; +- вы планируете предоставлять разные сервисы своим пользователям; +- вам требуется получение данных по своей организации, а также использование партнёрского сервиса (если есть прямая интеграция банка и ERP-системы пользователя и есть отдельная интеграция продукта пользователя с Alfa API / Alfa ID). + +Для получения нескольких `client_id` вам необходимо запросить у сотрудников Банка отдельный `client_id` для каждой интеграции, а также учитывать наличие нескольких `client_id` при реализации интеграции. + +--- + +### Навигация + +[← Отзыв договора](/products/alfa-api/documentation/articles/connection/articles/revoke/revoke) | [TLS-сертификат →](/products/alfa-api/documentation/articles/connection/articles/tls/tls) + +--- + +### Содержание раздела «Подключение к Alfa API» + +- [Как подключить](/products/alfa-api/documentation/articles/connection/articles/instruction/instruction) +- [Подписание договора](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding) +- [Отзыв договора](/products/alfa-api/documentation/articles/connection/articles/revoke/revoke) +- **Client ID** (текущая страница) +- [TLS-сертификат](/products/alfa-api/documentation/articles/connection/articles/tls/tls) +- [Client secret (POST)](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_secret.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_secret.md new file mode 100644 index 0000000..451258b --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/client_secret.md @@ -0,0 +1,88 @@ +# Client secret + +**Типы интеграции:** `B2B` | `B2C` | `H2H` +**Метод:** `POST` + +> [!IMPORTANT] +> **Внимание** +> Получить и заменить `client_secret` можно двумя способами: +> +> 1. С помощью кнопки в карточке интеграции на **Портале разработчика**. +> 2. С помощью описанного ниже API-метода. + +--- + +## Эндпоинты + +| Среда | URL | +| :------------ | :----------------------------------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/clients/{clientId}/client-secret` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/clients/{clientId}/client-secret` | + +--- + +## Описание + +`client_secret` представляет собой уникальную строку символов, которая генерируется один раз и не меняется в процессе работы. Достаточно получить его **один раз** и **не менять** в дальнейшем. + +При необходимости вы можете использовать этот метод для замены `client_secret` или в случае его компрометации для получения нового. + +Если оперативная замена `client_secret` невозможна, необходимо уведомить Банк о факте компрометации по адресу: [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :----- | :------------- | :----------------------------- | +| **Accept** | string | required | Должен быть `application/json` | + +### PATH (Путь) + +| Атрибут | Тип | Обязательность | Описание | +| :----------- | :----- | :------------- | :--------------------------------- | +| **clientId** | string | optional | Идентификатор партнёрского сервиса | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request POST 'https://baas.alfabank.ru/oidc/clients/{clientId}/client-secret' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :--------------- | :----- | :---------------------------------------- | +| **clientId** | string | Идентификатор партнёрского сервиса | +| **clientSecret** | string | Новый секретный ключ партнёрского сервиса | + +**Пример ответа:** + +```json +{ + "clientId": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "clientSecret": "Qwerty1234567890Qwerty1234567890!" +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :------ | :------------- | :---------------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверный формат запроса или отсутствуют обязательные параметры. | +| **401** | Unauthorized | `invalid_token` — ошибка авторизации. | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса. | + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_signing.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_signing.md new file mode 100644 index 0000000..8629fb0 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_signing.md @@ -0,0 +1,78 @@ +Вот очищенная и структурированная версия документа в формате Markdown. + +--- + +# Подписание договора + +**Теги:** `B2B` `B2C` `H2H` + +Для подписания договора на информационно–технологическое взаимодействие посредством Alfa API необходимо выполнить следующие шаги: + +### 1. Зайдите в Альфа-Бизнес +Зайдите в Альфа-Бизнес любым удобным для вас способом. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/1.png) + +Далее на странице второго фактора аутентификации введите полученный на телефон otp-ĸод (sms, push). +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/2.png) + +Вы зашли в Альфа-Бизнес. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/3.png) + +--- + +### 2. Перейдите во «Все сервисы и продукты» +Перейдите на страницу **Все сервисы и продукты** и выберите **Alfa API** в разделе **Обслуживание бизнеса**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/4.png) + +При отсутствии на странице пункта «Alfa API» отправьте письмо на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +--- + +### 3. Подключите Alfa API +На открывшемся лендинге нажмите на кнопку **Подключить Alfa API**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/5.png) + +Выберите необходимую организацию (при наличии нескольких организаций). +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/6.png) + +--- + +### 4. Подпишите договор +Внимательно ознакомьтесь с текстом договора. При необходимости введите e-mail для технических и для иных запросов. Нажмите на кнопку **Подписать**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/7.png) + +Далее на странице введите полученный на телефон otp-ĸод (sms, push). +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/8.png) + +Или подпишите договор при помощи усиленной квалифицированной электронной подписи (**УКЭП**). *Обратите внимание, что данный функционал доступен не всем пользователям.* + +Вы успешно подключили Alfa API. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/9.png) + +--- + +### 5. Просмотрите подписанный договор +Для просмотра договора необходимо нажать в верхнем правом углу на наименование компании. В появившейся боковой панели выберите **Настройки**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/10.png) + +Далее необходимо выбрать карточку **Управление согласиями**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/11.png) + +В разделе **Alfa API** будет отображаться подписанный вами договор. Для просмотра нажмите **Прочитать согласие**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/12.png) + +В открывшемся окне вы сможете прочитать договор и скачать его в формате **PDF**. +![image](/assets/developers-portal.docs.alfa-api/articles/connection/articles/onboarding/files/13.png) + +--- + +### 6. Приступайте к тестированию Alfa API +После успешного подписания договора вы можете: +* Получить тестовые учётные данные [на Портале разработчика](/products/alfa-api/documentation/articles/sandbox/sandbox). +* Приступить к тестированию Alfa API [в Песочнице](/products/alfa-api/documentation/articles/sandbox/sandbox). + +Для работы с Порталом вашему разработчику предварительно необходимо получить права на управление настройками Alfa API. Как их назначить, описано [на странице Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights). + +--- +**Навигация:** +← [Как подключить](/products/alfa-api/documentation/articles/connection/articles/instruction/instruction) | [Отзыв договора](/products/alfa-api/documentation/articles/connection/articles/revoke/revoke) → diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_termination.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_termination.md new file mode 100644 index 0000000..7af8406 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/contract_termination.md @@ -0,0 +1,55 @@ +# Отзыв договора + +**Теги:** `B2B` `B2C` `H2H` + +Для отзыва договора на информационно–технологическое взаимодействие посредством Alfa API необходимо выполнить следующие шаги: + +### 1. Зайдите в Альфа-Бизнес + +Зайдите в [Альфа-Бизнес](https://link.alfabank.ru) любым удобным для вас способом. +![Скриншот входа](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/1.png) + +Далее на странице второго фактора аутентификации введите полученный на телефон otp-ĸод (sms, push). +![Скриншот ввода кода](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/2.png) + +Вы зашли в Альфа-Бизнес. +![Скриншот личного кабинета](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/3.png) + +### 2. Перейдите в «Управление согласиями» + +Нажмите в верхнем правом углу на наименование компании. В появившейся боковой панели выберите **Настройки**. +![Скриншот настроек](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/4.png) + +Выберите карточку **Управление согласиями**. +![Скриншот управления согласиями](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/5.png) + +### 3. Отзовите договор + +В разделе **Alfa API** будет отображаться подписанный вами договор на информационно–технологическое взаимодействие посредством Alfa API. Для отзыва договора необходимо нажать на кнопку **Отозвать**. +![Скриншот раздела Alfa API](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/6.png) + +Подтвердите своё намерение, нажав на кнопку **Да, расторгнуть**. +![Скриншот подтверждения](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/7.png) + +### 4. Подпишите уведомление + +Внимательно ознакомьтесь с текстом уведомления. Нажмите на кнопку **Подписать уведомление**. +![Скриншот уведомления](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/8.png) + +Далее на странице введите полученный на телефон otp-ĸод (sms, push). +![Скриншот подтверждения кодом](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/9.png) + +Договор отозван. +![Скриншот результата](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/10.png) + +### 5. Просмотрите отозванный договор + +Для просмотра отозванного договора необходимо выбрать вкладку **Отозванные согласия**. +![Скриншот архива согласий](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/connection/articles/revoke/files/11.png) + +--- + +**Навигация:** + +- ← [Подписание договора](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding) +- → [Client ID](/products/alfa-api/documentation/articles/connection/articles/clientid/clientid) diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/how_to_connect.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/how_to_connect.md new file mode 100644 index 0000000..894e053 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/how_to_connect.md @@ -0,0 +1,26 @@ +*Подключение к Alfa API / Как подключить* + +`POST` `B2B` `B2C` `H2H` + +# Как подключить + +> ### Внимание +> Если вы ещё не являетесь клиентом Альфа-Банка, то для подключения к Alfa API вам необходимо открыть [счёт](https://alfabank.ru/sme/quick/docstariffs/), оформить [расчётно-кассовое обслуживание](https://alfabank.ru/sme/) и подключить [Альфа-Бизнес](https://alfabank.ru/corporate/rko/internet-bank/#form). + +1. **Подпишите договор** + [Подпишите договор](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding). + + Комиссия за подключение и использование не взимается. Вопросы по заключению договора можно направлять на почту [alfa_api@alfabank.ru](https://developers.alfabank.rumailto:alfa_api@alfabank.ru). + +2. **Проверьте тестовую интеграцию** + Получите тестовые учётные данные и настройте тестовую интеграцию [на Портале разработчика](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/test/test), реализуйте и протестируйте аутентификацию в Alfa ID и вызов методов Alfa API [в песочнице](https://developers.alfabank.ru/products/alfa-api/documentation/articles/sandbox/sandbox). + +3. **Подготовьтесь к промышленной интеграции** + Создайте интеграцию в проме, выпустите TLS-сертификат и `client_secret` . Подробнее [в инструкции](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/prod/prod). + +4. **Используйте Alfa API** + +Если вы ещё не являетесь клиентом Альфа-Банка, то для подключения к Alfa API вам необходимо открыть [счёт](https://alfabank.ru/sme/quick/docstariffs/), оформить [расчётно-кассовое обслуживание](https://alfabank.ru/sme/) и подключить [Альфа-Бизнес](https://alfabank.ru/corporate/rko/internet-bank/#form). + +--- +[← Сертификаты для Linux](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/linux/linux) [← Подписание договора](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding) diff --git a/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/tls-cert.md b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/tls-cert.md new file mode 100644 index 0000000..ab3e290 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Подключение_к_Alfa_API/tls-cert.md @@ -0,0 +1,154 @@ +# TLS-сертификат + +`B2B` `B2C` `H2H` + +Взаимодействие между вами и Банком реализовано с использованием двухстороннего TLS-соединения (поддерживаемая версия TLS 1.2), для которого необходимо выпустить сертификат. + +--- + +## Инструкция по выпуску сертификата + +Для выпуска сертификата необходимо сгенерировать закрытый ключ и запрос на сертификат в OpenSSL, получить выпущенный сертификат и установить в своей системе: + +### 1. Используйте готовый файл конфигурации + +Воспользуйтесь заранее подготовленным конфигурационным файлом: [openssl_INNLE.cnf](/assets/developers-portal.docs.alfa-api/articles/connection/articles/tls/files/openssl_INNLE.cnf). + +> **Внимание** +> Данный файл уже содержит все необходимые атрибуты и не требует внесения изменений. Все остальные параметры будут введены вручную через терминал в процессе генерации закрытого ключа и запроса на сертификат. + +> **Важно** +> Если возникает ошибка `object identifier routines:OBJ_create:oid exists`, необходимо закомментировать строку с объявлением этого OID в начале файла: `INNLE=1.2.643.100.4`. + +### 2. Сгенерируйте закрытый ключ + +1. Откройте терминал и перейдите в папку с файлом. Если это «Загрузки»: + `cd ~/Downloads` +2. Убедитесь, что файл на месте командой `ls`. +3. Сгенерируйте закрытый ключ: + `openssl genrsa -des3 -out Company.key 2048` +4. Задайте пароль для ключа (**PEM pass phrase**) и запомните его. +5. В папке появится файл `Company.key`. + +> **Рекомендация для Mac OS** +> Введите дважды пароль от вашего Mac OS, когда терминал запросит подтверждение действий. + +### 3. Сгенерируйте запрос на сертификат (CSR) + +1. Введите команду: + `openssl req -utf8 -config openssl_INNLE.cnf -key Company.key -new -sha256 -out Company.csr` +2. Атрибут `CLIENT_ID`, а также поля `An optional company name` и `A challenge password` являются опциональными (можно оставить пустыми). +3. Введите данные организации (название, ФИО, ИНН), когда терминал их запросит. + +> **Рекомендации для заполнения полей** +> Поля `OrganizationName` и `CommonName` можно заполнять транслитом или кириллицей (UTF-8). +> **ИНН:** строго 10 цифр для ЮЛ и 12 цифр для ИП (без пробелов). +> Поля `CountryName` и `INNLE` формируют имя профиля в LDAP и должны быть точными. + +### 4. Проверьте атрибуты в subject + +Проверьте созданный запрос командой: +`openssl req -config openssl_INNLE.cnf -noout -text -in Company.csr` + +**Пример корректного ответа:** + +```text +Subject: C=RU, L=Moscow, O=Company Name, CN=Ivanov Ivan Ivanovich/emailAddress=example@company.ru/INNLE=01234567890/CLIENT_ID=b95e04ed-91fe-430a-a101-894f06f3ab2a +``` + +### 5. Отправьте запрос в Банк + +Отправьте файл `Company.csr` на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +- **Тема:** «Запрос на сертификат». +- **Отправитель:** почта, указанная в Договоре. +- **Имя файла:** название организации на латинице. +- **В письме:** укажите e-mail для уведомлений об истечении срока сертификата. + +> **Важно!** Никому и никогда не передавайте файл закрытого ключа (`.key`). + +### 6. Получите сертификат + +Банк пришлет сертификат с адреса `alfa_api@alfabank.ru`. + +- **Срок действия:** 375 дней. По истечении нужно выпустить новый. + +### 7. Сборка файла контейнера pfx + +Для установки в систему соберите контейнер командой: +`openssl pkcs12 -export -out Company.pfx -inkey Company.key -in Company.cer -certfile keys\root_apica_2022.cer -certfile keys\sub_root_apica_2022.cer` + +### 8. Действия при компрометации + +Если закрытый ключ был украден или утерян, немедленно напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru) для отзыва и перевыпуска. + +--- + +## Требования к сертификату + +### Global Subject (Обязательные поля) + +| Атрибут | Значение | +| :------------------- | :--------------------------------- | +| **CountryName** | Код страны (ISO). Для России: `RU` | +| **OrganizationName** | Название организации | +| **CommonName** | ФИО представителя организации | +| **EmailAddress** | Служебный адрес для связи | + +### Variable Subject (Зависит от формы собственности) + +| Атрибут | Значение | +| :------------------------ | :------------------------------------ | +| Для ЮЛ в России | `INNLE = 1.2.643.100.4` | +| Для иностранных партнёров | `FOREIGNID = 1.3.6.1.4.1.16745.100.1` | +| Идентификатор сервиса | `CLIENT_ID = 1.3.6.1.4.1.16745.100.2` | + +--- + +## Настройка UTF-8 для кириллицы + +### Windows + +1. **Панель управления** > **Часы и регион** > **Регион**. +2. Вкладка **Дополнительно** > **Изменить язык системы**. +3. Включите чекбокс: «Бета-версия: Использовать Юникод (UTF-8) для поддержки языка во всем мире». +4. Перезагрузите ПК. + +### MacOS + +1. Откройте **Терминал**. +2. В меню: **Terminal** > **Настройки**. +3. Вкладка **Кодировки**: убедитесь, что выбрана «Unicode (UTF-8)». + +--- + +## Использование сертификата + +Использование TLS-сертификата обязательно для установки mTLS-соединения. Пример запроса через **cURL**: + +```bash +curl -X GET https://baas.alfabank.ru/api/endpoint \ + -v --cert Company.cer \ + --key Company.key \ + -H 'Accept: application/json' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Content-Type: application/json' +``` + +--- + +## Повторный выпуск сертификата + +За **1 месяц** до истечения срока вам придет уведомление. Необходимо сформировать новый запрос по инструкции выше. + +> **Внимание** +> При перевыпуске рекомендуем: +> +> - Установить защиту на удаление закрытого ключа. +> - Перезаписать старый закрытый ключ на новый. + +_В случае утери сертификата или несвоевременного обновления, ответственность за простой API возлагается на сторону клиента._ + +--- + +← [Client ID](/products/alfa-api/documentation/articles/connection/articles/clientid/clientid) | [Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) → diff --git a/_docs/alfabank/payin_and_kyc/Портал_разработчика/access_rights.md b/_docs/alfabank/payin_and_kyc/Портал_разработчика/access_rights.md new file mode 100644 index 0000000..324e802 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Портал_разработчика/access_rights.md @@ -0,0 +1,57 @@ +# Права доступа + +По умолчанию доступ к Порталу разработчика имеет только руководитель вашей организации. + +Для предоставления доступа к Порталу разработчика другим пользователям руководителю необходимо в **Альфа-Бизнес** создать роль с правами на управление настройками Alfa API и присвоить её пользователю. + +> **Внимание** +> В случае если у вас ИП, права разработчика можно назначить: +> +> - от имени самого индивидуального предпринимателя с ролью «Руководитель»; +> - от имени любого другого сотрудника ИП с ролью «Руководитель». В таком случае потребуется подтверждение назначения от владельца ИП. Подробнее в инструкции ниже. + +--- + +## Инструкция по настройке прав + +### Шаг 1. Перейдите в раздел «Пользователи и роли» + +1. На главном экране Альфа-Бизнес перейдите в настройки компании. +2. В разделе **Моя компания** выберите карточку **Пользователи и роли**. + +### Шаг 2. Создайте новую роль + +> **Внимание:** Если ранее вы уже создавали роль с правами на управление Alfa API, этот шаг можно пропустить. + +1. Нажмите **Создать роль**. +2. Укажите название роли. +3. Настройте права: новую роль рекомендуется создавать на основании прав руководителя, сбросив лишнее. +4. Нажмите **Снять все**, чтобы сбросить текущие права. +5. В разделе **Обслуживание бизнеса** выберите **Alfa API** и укажите необходимые полномочия. +6. При необходимости добавьте права из других разделов. +7. Нажмите **Создать роль** для сохранения. + +### Шаг 3. Назначьте роль разработчику + +> **Примечание:** Если пользователь еще не подключен к компании, нажмите «Подключить пользователя», заполните данные и выберите созданную роль. + +1. В разделе **Пользователи** нажмите на три точки справа от нужного сотрудника. +2. Выберите **Сменить роль**. +3. В открывшейся форме выберите созданную роль и нажмите **Сменить**. +4. Подтвердите смену роли кодом из СМС. + - _Для ИП:_ Если роль назначает не сам владелец, будет создано заявление, которое владелец должен подписать в своем личном кабинете. +5. После успешного назначения статус пользователя изменится на **Подключён**. + +--- + +## Требования к полномочиям для корректной авторизации + +Для корректной работы H2H-интеграций ключ доступа (`access_token` / `API Key`) должен получать пользователь, у которого есть полномочия на использование выбранных сервисов и продуктов. + +### Особенности способов авторизации: + +- **При использовании ACF H2H:** Авторизацию в Alfa ID должен проходить пользователь, у которого в Альфа-Бизнес настроены соответствующие полномочия на использование выбранных `scopes`. Если вы хотите использовать учетные данные разработчика, руководитель должен выдать ему соответствующие права в разделе «Пользователи и роли». +- **При использовании авторизации по API Key:** Выпускать ключ должен пользователь, имеющий права на выбранные продукты. Если у пользователя нет прав (например, на просмотр выписок), то выпущенный им `API Key` не будет работать для этого сервиса. + +**Пример:** +Если вы выдали разработчику права на _редактирование интеграций_, но не дали прав на _просмотр выписки_, то созданный им `API Key` для сервиса выписок (`transactions`) работать не будет. Ключ должен выпускать либо руководитель, либо сотрудник с полным доступом к нужным данным. diff --git a/_docs/alfabank/payin_and_kyc/Портал_разработчика/api_key_managment.md b/_docs/alfabank/payin_and_kyc/Портал_разработчика/api_key_managment.md new file mode 100644 index 0000000..5db627a --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Портал_разработчика/api_key_managment.md @@ -0,0 +1,81 @@ +# Управление API Key + +Портал разработчика позволяет управлять `API Key` – ключами доступа для упрощённой авторизации запросов в H2H-интеграциях. Подробнее о ключе и доступных по нему сервисах [на странице API Key](/products/alfa-api/documentation/articles/api-key/api-key). + +Для настройки авторизации с помощью `API Key` вам необходимо выпустить ключ для H2H-интеграции, скопировать его и вручную добавить в свои рабочие инструменты. Значение ключа передаётся в заголовке: `Authorization: ApiKey {API Key}`: + +### Пример запроса с использованием API Key + +```bash +curl -X GET https://baas.alfabank.ru/api/endpoint \ + -H 'Authorization: ApiKey akytnps_YfSpCMb0_Uat5NX4p3c7A50hf27Qapk7nXYQ81h659tSwKml87xA5IhpBXXnpKSVypV60dI2l_2918090335' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Выпуск API Key для прома + +Перед выпуском `API Key` для промышленной H2H-интеграции рекомендуется сначала пройти описанные ниже шаги для тестовой H2H-интеграции в рабочей среде «Песочница» и протестировать ключ, и только после этого приступать к выпуску ключа для промышленной H2H-интеграции. + +> **Важно** +> Выпускать `API Key` необходимо пользователю, у которого в Альфа-Бизнес настроены соответствующие полномочия на использование выбранных при выпуске ключа продуктов и сервисов. Если у пользователя отсутствуют эти полномочия, руководителю организации необходимо выдать их пользователю в Альфа-Бизнес (в разделе **Профиль** – **Пользователи и роли**) или выпустить ключ самому. + +### Шаг 1. Нажмите "Выпустить API Key" + +Нажмите **Выпустить ключ** в правой части карточки H2H-интеграции. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_1.png) + +### Шаг 2. Заполните данные для API Key + +Укажите IP-адреса, с которых будут отправляться запросы с использованием `API Key`. Отправка запросов с использованием `API Key` будет доступна только с указанных IP-адресов. + +Для одного API Key вы можете указать не более 20 IP-адресов. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_2.png) + +Укажите сервисы и продукты, доступ к которым вы хотите получать с помощью `API Key`. Вам будут доступны сервисы и продукты из набора `scopes` редактируемой H2H-интеграции, доступ к которым возможен с помощью `API Key`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_3.png) +Далее проверьте и сохраните внесённые изменения. + +### Шаг 3. Скопируйте и сохраните API Key + +После завершения выпуска `API Key` вы получите уведомление. Скопируйте его и вручную добавьте в ваши рабочие инструменты так, чтобы при отправке запросов по H2H-интеграции в запросах передавался заголовок `Authorization: ApiKey {API Key}`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_4.png) + +**Срок действия:** Срок действия `API Key` неограничен, но ключ будет автоматически отозван, если с момента последнего запроса прошло более **30 дней**. + +В случае потери данных либо компрометации ключа вы можете перевыпустить его. Также вы всегда можете отозвать `API Key`, если больше не хотите использовать упрощённый способ авторизации. + +--- + +## Перевыпуск API Key + +### Шаг 1. Нажмите "Перевыпустить API Key" + +Нажмите на три точки в правом верхнем углу карточки H2H-интеграции и выберите **Перевыпустить API Key**. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_1.png) + +### Шаг 2. Отредактируйте данные для API Key + +При необходимости отредактируйте данные для `API Key`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_2.png) +Далее проверьте внесённые изменения и нажмите «Перевыпустить». + +### Шаг 3. Скопируйте и сохраните API Key + +После перевыпуска `API Key` вы получите уведомление. Вам будет необходимо скопировать его и заменить в ваших рабочих инструментах. При перевыпуске `API Key` старый ключ, привязанный к этой интеграции, будет автоматически отозван. + +Срок действия `API Key` неограничен, но ключ будет автоматически отозван, если с момента последнего запроса прошло более 30 дней. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_3.png) + +--- + +## Отзыв API Key + +Для отзыва ключа доступа нажмите на три точки в правом верхнем углу карточки интеграции, выберите **Отозвать API Key** и подтвердите свои действия. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/revoke_1.png) +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/revoke_2.png) + +В результате отзыва ключа упрощённая авторизация будет недоступна. При необходимости вы всегда можете выпустить новый `API Key`. diff --git a/_docs/alfabank/payin_and_kyc/Портал_разработчика/creating_prod_integration.md b/_docs/alfabank/payin_and_kyc/Портал_разработчика/creating_prod_integration.md new file mode 100644 index 0000000..81343ca --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Портал_разработчика/creating_prod_integration.md @@ -0,0 +1,85 @@ +# Создание интеграции в проме + +**Метки:** `β-ТЕСТ` `B2B` `B2C` `H2H` + +После успешного тестирования продуктов и сервисов в песочнице вам станет доступно создание интеграций в проме. + +## Создание промышленной интеграции + +### Шаг 1. Нажмите «Создать интеграцию» + +> **Внимание** +> Одновременно у вас может быть не более 5 промышленных интеграций. + +Нажмите **Создать интеграцию** в степпере или в списке интеграций, находясь в рабочей среде «Пром» (для выбора рабочей среды используйте переключатель в правом верхнем углу Портала разработчика). + +**Важно!** В случае если вы работаете в режиме группы компаний, перед созданием новой интеграции необходимо перейти в профиль пользователя и выбрать компанию, для которой вы хотите создать интеграцию. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/1.png) + +--- + +### Шаг 2. Выберите тип интеграции + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/2.png) + +--- + +### Шаг 3. Заполните основную информацию + +Укажите название интеграции (рекомендуется использовать то же название, что и у соответствующей тестовой интеграции), `redirect_uri` и тип клиентов (выбор типа клиентов доступен только для партнёрских интеграций). + +В одной интеграции вы можете указать не более 20 `redirect_uri`. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/3.png) + +--- + +### Шаг 4. Выберите сервисы и продукты + +> **Важно** +> Вам будут доступны сервисы и продукты, по которым при тестировании было выполнено не менее одного успешного запроса в песочнице. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/4.png) + +--- + +### Шаг 5. Завершите создание промышленной интеграции + +Проверьте параметры интеграции перед её сохранением. + +Для создания интеграции потребуется некоторое время. После завершения создания промышленной интеграции вы получите уведомление: + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/5.png) + +--- + +### Шаг 6. Разблокируйте промышленную интеграцию + +После создания интеграция отображается в статусе **«Заблокирована»**. + +Для разблокирования интеграции создайте запрос на TLS-сертификат и отправьте его на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). Подробнее [на странице TLS-сертификат](/products/alfa-api/documentation/articles/connection/articles/tls/tls). + +Если вы уже выпускали сертификат, повторно выпускать его не нужно. Вместо этого необходимо сообщить о готовности к промышленной интеграции на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). После этого интеграция будет разблокирована и перейдёт в статус **«Новая»**. + +--- + +### Шаг 7. Активируйте промышленную интеграцию + +Чтобы активировать интеграцию, необходимо получить `client_secret`. Для этого нажмите на иконку в карточке интеграции: + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/6.png) + +Скопируйте `client_secret` и добавьте его в ваши рабочие инструменты. Получить его можно также с помощью [метода](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret). + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/7.png) + +После того как вы получите `client_secret`, интеграция перейдет в статус **«Активна»** и будет доступна к использованию в промышленной среде. + +--- + +## Подключение новых продуктов к текущей промышленной интеграции + +Для подключения новых продуктов и сервисов к промышленной интеграции сначала добавьте новые `scopes` в режиме редактирования тестовой интеграции и протестируйте их в песочнице. + +После успешного тестирования отредактируйте промышленную интеграцию, добавив новые `scopes`. После этого новые продукты или сервисы будут доступны в промышленной среде. diff --git a/_docs/alfabank/payin_and_kyc/Портал_разработчика/testing.md b/_docs/alfabank/payin_and_kyc/Портал_разработчика/testing.md new file mode 100644 index 0000000..b208df8 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Портал_разработчика/testing.md @@ -0,0 +1,55 @@ +# Тестирование + +**Метки:** `β-ТЕСТ` `B2B` `B2C` `H2H` + +Перед созданием первой промышленной интеграции или подключением новых продуктов и сервисов к текущей промышленной интеграции необходимо проверить работу интеграций в песочнице. + +При входе на Портал разработчика вы увидите две тестовые интеграции: одна для тестирования партнёрской интеграции, другая — для тестирования H2H-интеграции. В зависимости от ваших целей вы редактируете нужную интеграцию в рабочей среде «Песочница» и тестируете её. + +--- + +### Шаг 1. Настройте тестовую интеграцию + +Для редактирования тестовой интеграции нажмите на три точки в правом верхнем углу карточки и выберите **Редактировать интеграцию**. + +![Редактирование интеграции](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/test/files/1.png) + +1. **Вкладка «Информация»**: + - При необходимости отредактируйте название интеграции. + - Укажите необходимые `redirect_uri` для переадресации пользователя после авторизации через Alfa ID. + - _Пример redirect_uri:_ [https://romashka.ru](https://romashka.ru). + - **Важно:** В одной интеграции вы можете указать не более 20 `redirect_uri`. + +![Настройка информации](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/test/files/2.png) + +2. **Вкладка «Scopes»**: + - Выберите продукты и сервисы, которые вы хотите подключить в Alfa API. + - Если вы не нашли нужные `scopes`, напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +![Выбор Scopes](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/test/files/3.png) + +3. **Сохранение**: + - После завершения редактирования тестовой интеграции необходимо сохранить внесённые изменения. + +![Сохранение изменений](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/test/files/4.png) + +--- + +### Шаг 2. Протестируйте интеграцию + +Выполните запросы по выбранным `scopes` в тестовой среде в соответствии с [инструкцией по тестированию](/products/alfa-api/documentation/articles/sandbox/sandbox), используя учётные данные тестовой интеграции. + +После успешного тестирования в песочнице вам станет доступно создание промышленной интеграции со `scopes`, по которым было выполнено не менее одного успешного запроса в песочнице. + +--- + +### Дополнительная информация + +Вы можете использовать текущие интеграции в песочнице для тестирования новых сервисов и продуктов, добавляя новые `scopes` в режиме редактирования тестовой интеграции. После успешного тестирования в песочнице вы сможете добавить новые `scopes` в промышленную интеграцию и использовать их в своих сервисах. + +--- + +**Навигация:** + +- [← Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights) +- [Создание интеграции в проме →](/products/alfa-api/documentation/articles/selfservice/articles/prod/prod) diff --git a/_docs/alfabank/payin_and_kyc/Портал_разработчика/what_is_for.md b/_docs/alfabank/payin_and_kyc/Портал_разработчика/what_is_for.md new file mode 100644 index 0000000..aa5d1b1 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Портал_разработчика/what_is_for.md @@ -0,0 +1,64 @@ +# Для чего нужен Портал разработчика + +**Портал разработчика** предназначен для управления интеграциями Alfa API. С помощью него вы можете создавать новые и редактировать текущие интеграции, подключать новые продукты и сервисы, а также активировать упрощённую авторизацию запросов с помощью API Key. + +Портал разработчика станет доступен после того, как вы [подключите Alfa API](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding). + +> **Внимание** +> Для работы с порталом вашему разработчику необходимо получить права на управление интеграциями Alfa API. Как их назначить, описано [в статье Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights). + +--- + +## Запуск первой промышленной интеграции + +1. **Войдите на Портал разработчика** + Вход осуществляется через Портал документации по кнопке **Войти** и возможен только под учётной записью сотрудника организации, подключённой к Alfa API. + ![Интерфейс входа](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/enter.png) + +2. **Проверьте тестовую интеграцию** + [Как настроить интеграцию в песочнице и протестировать её](/products/alfa-api/documentation/articles/selfservice/articles/test/test) + +3. **Создайте интеграцию в проме** + [Как создать промышленную интеграцию](/products/alfa-api/documentation/articles/selfservice/articles/prod/prod) + +4. **Выпустите промышленный TLS-сертификат** + [Как выпустить TLS-сертификат](/products/alfa-api/documentation/articles/connection/articles/tls/tls) + +5. **Используйте промышленную интеграцию в своих сервисах** + +При необходимости вы можете подключать новые продукты и сервисы к текущей интеграции и создавать новые интеграции на Портале разработчика. Также вы можете настроить упрощённую авторизацию по H2H-интеграциям с помощью [API Key](/products/alfa-api/documentation/articles/selfservice/articles/api-key/api-key). + +--- + +## Выбор рабочей среды + +На Портале разработчика предусмотрены две рабочие среды: + +- **«Песочница»** — для редактирования тестовых интеграций. +- **«Пром»** — для управления промышленными интеграциями. + +Выбор рабочей среды осуществляется с помощью переключателя в правом верхнем углу портала. + +![Выбор среды](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/mode.png) + +--- + +## Работа с группой компаний + +Пользователи с доступом к интеграциям нескольких компаний могут работать в двух режимах: группы компаний или одной выбранной компании. Это позволяет работать с интеграциями всех доступных компаний в едином окне. + +### Как переключить режим: + +1. Перейдите в профиль пользователя в правом верхнем углу Портала разработчика. + ![Профиль пользователя](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/profile.png) + +2. Выберите режим отображения компаний: + - Карточка **Все компании** — чтобы работать с интеграциями всех компаний одновременно. В этом режиме доступна единая таблица со всеми интеграциями. + - Карточка **конкретной компании** — чтобы работать только с интеграциями выбранной организации. + +![Выбор компании](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/holding.png) +![Единая таблица](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/expanded-view.png) + +--- + +**Далее:** [Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights) | [Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-ghost.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-ghost.md new file mode 100644 index 0000000..14cf4f8 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-ghost.md @@ -0,0 +1,109 @@ +# Шифрование JSON ГОСТ-сертификатом + +Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +> [!IMPORTANT] +> **Внимание** +> Для шифрования и подписания сообщения необходимо предварительно загрузить сертификат, используя следующий [метод](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates). Если вы уже загружали сертификат, используя данный метод — повторно выполнять эту операцию не нужно. + +--- + +## Подпись и шифрование JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **ГОСТ Р 34.10-2012 256 бит** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса (Header):** + +- `"alg": "GOST3410_2012_256"` +- `"typ": "JWT"` +- `"cty": "JWS"` +- `"kid": "серийный номер сертификата"` +- `"b64": true` + +**Пример JWS:** + +```text +ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Зашифровать запрос + +Зашифруйте полученный на шаге два JWS-контейнер алгоритмом **ГОСТ 34.12.2015** (блочный шифр с длиной блока n = 64 бит «Магма») открытым ключом сертификата Альфа-Банка, чтобы получился **PKCS7-контейнер**, и передайте его в теле запроса. Для получения сертификата напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +**Информация об используемых стандартах ТК 26:** + +- **Алгоритм экспорта ключей KExp15** на основе симметричного блочного шифра "Магма". OID: `1.2.643.7.1.1.7.1.1` +- **Алгоритм шифрования послания "Магма"** в режиме гаммирования CTR с механизмом преобразования ключа ACPKM с вычислением имитовставки. OID: `1.2.643.7.1.1.5.1.2` + +**Пример PKCS7:** + +```text +MIITdQYJKoZIhvcNAQcDoIITZjCCE2ICAQAxggIAMIIB/AIBADCCASIwggELMRgwFgYFKoUDZAESDTEwMjc3MDAwNjczMjgxGjAYBggqhQMDgQMBARIMMDA3NzI4MTY4OTcxMQswCQYDVQQGEwJSVTEYMBYGA1UECAwPNzcg0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxKjAoBgNVBAkMIdCj0LsuINCa0LDQu9Cw0L3Rh9C10LLRgdC60LDRjyAyNzEPMA0GA1UECwwG0KPQmNCRMSEwHwYDVQQKDBjQkNCeINCQ0JvQrNCk0JAt0JHQkNCd0JoxNTAzBgNVBAMMLNCi0JXQodCiINCj0KYgMi4wINCQ0J4gItCQ0JvQrNCk0JAt0JHQkNCd0JoiAhEG04uOAGGw+alPEEvlfneqGDAXBgkqhQMHAQEHAQEwCgYIKoUDBwEBBgEEgbcwgbQEKLyfbBL4H33ZmcqKiO1B85UCDlnD2qk05vlU+4dEg34KWZLsLQv05MYwZjAfBggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAMyQte/ak3j94OBDlA+o+CC/y4VldsMsFTA0z9zqXFR5LFLmyVop7VDJkzeXwk/BM+YIXwbWG0GnbebS3ZjuP/wQgKo8O42NksPcsAGvRWKaYYtk3RQfL9zrMZwdBtDroNjIwghE8BgkqhkiG9w0BBwEwGwYJKoUDBwEBBQECMA4EDJzOZEVIxIU3bLczkICCERA02+pMp1hYBL6KVvGmWD7NOqN0kOF5lrhPg+4Jwk2hbQiod2WFOmK0jOf3wUwF549eNMCRP5Clkz61K9b4p8CEFuodPJ65fetCUi7t1+EmSNwzBKRNzB8gNM4M12KIIJbCGpDAxyWHWe98ZgqDgCe7d/u8Lh5lqKrfrXrwHwqi+Ivdqe5ubpU37jZr1QvoWdyLocdBBoz3musKUDfuwM+tFoEydK9gK86knMXsD7ZJ3LJngy4ztGGdjBRjbF+Pg+RmR1UhCnDLEtCiJnMNN75735pXpFAgLVcUo2oexLRGh8Jw3Uh9+UthY2tRt11/e6iyrkGPmrMlcHd1poj/XC0bsIP6+kNwHMxITO2lkEKIL3B3CRZlNKMPx4dfnLt4u+cMCm+qyLqtXilxSDZp0yETzHy76ee+UdXr0kb3eGPcBidHPNpeb2EqjAE8UCuwmVfOpznl4kioEUNfCcrnPZDqHQTpNs35lQlQocyWPQOugP0OB6BC5/9kXKf5VPHcIMLeWzvor3cuac+nBaRNB4PzvwiAdBvwKp4asbvZak/MPf8I23gpdXGVtMajbUzJUlGd6Bz+G6Kz4vpUUW8IoVwXL/vPU+3N1jKbNyGvrPFrdaIoUJHu+9B92/LlmOpcxF5GssrM9MsC9e6cEl4Cq82QQn3w7AJCdHMDzgANk04cmNKDTl5DPL2YNjcmirXaVXKzO7W4Oa4PIyKAaR811tT9kKAxsJvAWODjM1wdDMSCUlK1C1DHfJdZneXY61sbbpYQoHGuC/Uo+5Z1xdLTYjjVMY5mJ/444zdWGY0Aa2BiS+vd28hx/uSlg0T93eLpJcuWvT5B5aDuBrSFPpMRCeC/VCpwfSbAAekVHGjMb1B/ABLLgbPGnTLH5RCJOUiImihn7LPhlGSop705d9TSwvItP4XO3xebqd0vpr0YvTXy8VRTzSI8UGAs+lzoGbDnqYdPYND5XR+P0vpPA3m5Yd2kBCJJoU9Z8Clzw5+Q/6X3bsa/aLmT4V3L5TZWX169gIip77EqtLUPEGEFHVUE+rmBWKcx6IBDazEsxJ4OAHkRZq7Ls6k5g3P30fwhHmXaTWGTIjRr78LHFPN15MbTthakEoAD4sMnXCmOnZtSskGyNY1U1C1Al0REql4U2dpUDebNcmTqAqwv6rPLCCA69brcXQ8ZFbyuWq39Fz4oN6OulVNNtQ6lhuTOyPCRiEIRWdW5bIROuWs1BD9M/xZOzCIJxuA/t5xusCk1BYx1D4e6cqiwpbPSAJZMDnWlNu1WT1QPEk55ihbTYGwfUmP4SUIJL8DWJvZgs7aD1ZZq5LxjZoghem8TlpwB+dlZ96geD1T6qez0DFSSL6NJkjFGkH1WYYZcTtomUrwg4yqjDlWbZOzSPAWcKwd1vkEruViOOH892FbxRUMC9EXRg4fTaRIfcgtfEO3fGAeB6fJv1pZMdNdLUOOHViuAZrhNDgBnWblqlIbl6HMmiWCoW7JryN2WXl/L1RybXO9QALAaNCmyN0zk+baqXz2ipne3CFkohucv1T++iC+SwQ+iNoxb3DfkRdBQfXPbdY75od4+g0YPN68XW3nAze1NT8kZw7Z5/bs+ZStilJTCfKx9VZaeHF+N7k4J9ll683UYp64gtxVcNx/1MQYkf6hgesh0YRtcf35HBUAilaF+1EStQHdN6tlfaB9rNwAehoHIegset/NeWBekVpo3DKLKX0qf3+J1qBr2q3nYKdApYJwgLRCtR46b865tu8puZAPLTqCk0gp0ay52kHsYxGPAeTyQsygMCQxGjcHsHJEJCEa+NvPNkBsYfick9PKe4gFJPyDiaM4yPPk6YE755Ow8OByHbSE6c4scL1CtinWIQWZJMdtN+77au7nyDwfVvIrQehnT0gWAiTZJcwsJjxpnhdhAsGkm7j1VeT4yCAAX0OvV55LVmGVVBINAJObCsybLuKA0MIPeLH4BPa/aMBGM/XigYPFVbW01PQheuWMTkGF1ru2gc2aqGKbiFY2XSbJ3u14fPUiTpLzV9bdyi15XDpVe9T4b6ioEAHzOjsTlMpwvQZOgyKw8KAyiJ1H+S8DzNlTrbzmpJyVYw8iiLceXepHMToFLnCnmey244g2dOKmMKHZT+xyMjSgiKQ8bNI7hIPhymjeQxxmYfwmfmXxSXX5bfjDuKo7Upt0GnbfKRUGKpJnm0bsK084Lxxy4XBrFQt0aNPTfAyhEylqhkctdpteIMM7gdWwQZrLhrKxJdFaU5HK0aFaIMfE4ANSC93Grpz31NgWlTKd1ZeTbnbP3vRE9wS6N+i/xI6Vmn0v928h/DPMDoiWkCx11+Ey1fAnR3inBTmVnM3j9+SIuo1tNaX2Xq4zoHXTMr5yaY9pvPPMCYrCLxX8J28bUmqR/cA5b+ot4fWyQDh0ascRk2wB2PptjcjQjxWED4vRWj/2oDNMx1lCuwPmagXAYWbDUql4LyknJUZGjePhP+7mDX6AtTtX+70jltAUlC5orD8L+IDKeRU2y+lCvdV8OfrE892XiFfOvPd6t+Pal0a0ML/Kbp7ZH642L5I73RyTFzAv06UPybwdpvEa8rssicVd3sjI5BJnJ2x3Jkl7QcSUqkk28Werjl0+/5F6C+xlJOgZ2tEX4SyiNxfVGd7dn0jsFzAzrfVqFp5tJ3f6IZ3hG4MetoQS2R3PXfETAoHz4qUE0XJ95OTxY9DCmDXtR5ce/5BC0EaJLnAexxwe+TC/kMjqUZTCKla3hhfZCG0ylGc4u8d6MtijTzkKZNiC9ww5q4T392uzltL4jp/YiHGNSvQMtgfjOeFKtNWHGMWJ/8hjYqTG5jEPWNnYwCNmxCW9Ut7jZPAnKomRiO4+cIEavgKiyiYqTBGHMDV6PZ5SvKOTATr3swLHBzSgqoczp992fWocAD9MSc+CK5oULQs2oduBWFJ5zQRuRGpjxqTjh64m1w0Ci2imHX9AY30ccpNjp/g5znWUexmioupdnZGMchy2RnFNMpflGrTGiyXgqsSSykwCLqB56pF/Qqg1v3Eq0NCWt9VKkFIi27SXfPW/jXTBs/r1EkZu2C8DqaTynjWmlo3L1yTrs1ZyXTDSiuQCzLKPEJoYHVIboZ8za1C6oVEnluh7b4rn5DLAgTgHcU2oZbu2qVePSCZwXj6tz9d74dU8DBbowTn33443YAC04VeSA8A+jsT4YKMdhCK8AkTQSAEtUjBj3Mb++T3XKEVth639oEfZ6mioIcjQ8ePu2|... (длинная строка сокращена) +``` + +### 4. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то запрос **не будет** расшифрован и подпись запроса не будет проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: ENCRYPTION` и отправить запрос, то запрос **будет** расшифрован и подпись будет проверяться. + +Банк дешифрует запрос и проверяет подпись. Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. Ошибка также будет подписана и зашифрована. Любые другие комбинации заголовков приведут к ошибке. + +--- + +## Дешифрование и проверка подписи JSON + +### 1. Дешифровать ответ + +- При заголовках `Accept: application/json` + `X-Response-ChannelSecurity: NO` ответ **не будет** подписан и зашифрован. +- При заголовках `Accept: application/jose` + `X-Response-ChannelSecurity: ENCRYPTION` ответ (включая ошибки) **будет** подписан и зашифрован. + +Полученный ответ будет в виде PKCS7-контейнера. Расшифруйте его с использованием вашего закрытого ключа. Используются те же стандарты ТК 26 (Магма, OID: `1.2.643.7.1.1.7.1.1` и `1.2.643.7.1.1.5.1.2`). + +### 2. Обработать дешифрованный ответ + +Полученный ответ будет представлен в виде компактной сериализации JWS (три части через точку): `Base64URL(Header)`, `Base64URL(Payload)`, `Base64URL(Signature)`. + +**Пример декодированного JWS:** + +| Закодированный | Раскодированный | +| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | +| `ewogICJhbGciIDog...` | **Header:** `{"alg": "GOST3410_2012_256", "typ": "JWT", "cty": "JWS", "kid": "6d38b8e0061b0f9a94f104be57e77aa18", "b64": true}` | +| `eyJkZWJpdFR1cm5vdmVyI...` | **Payload:** `{"debitTurnover": {"amount": 0, "currencyName": "RUR"}}` | + +### 3. Проверить подпись ответа от Банка + +Используйте открытый ключ сертификата Банка для проверки подписи. Для получения сертификата напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). В поле `kid` заголовка JWS будет указан серийный номер сертификата Банка. + +### 4. Обработать ответ в формате JSON + +**Пример итогового ответа:** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-rsa.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-rsa.md new file mode 100644 index 0000000..9b6431a --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/encription/json-rsa.md @@ -0,0 +1,147 @@ +# Шифрование JSON RSA-сертификатом + +**Метки:** `B2B` `B2C` `H2H` + +Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке Вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +> [!IMPORTANT] +> **Внимание** +> Для шифрования сообщения необходимо предварительно выпустить сертификат в УЦ Альфа-Банка, используя сервис [«Электронная подпись»](/products/alfa-api/documentation/articles/signature/signature). Если Вы уже выпускали сертификат — повторно выпускать не нужно. + +--- + +## Подписание и шифрование JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **RS256** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса:** + +- **Заголовок (Header):** + - `"kid"`: "серийный номер сертификата" + - `"typ"`: "JWT" + - `"alg"`: "RS256" +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS:** +`eyJhbGciOiJSUzI1NiIsImtpZCI6IjYxMDAwMzYzY2NiNzU5Y2I0NDg2MDc4NjVkMDAwMTAwMDM2M2NjIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY1Nzg4MjY4OSwiZXhwIjoxNjU3ODg2Mjg5fQ.ApKNzZ9kLMtBY3LzReSHQ7_AyDnzocGo9GTQFRmxTiRS7Lj7a55Kr4ziwZAmmwloF1063JJMOaU0lS947q6_hSct9pxzPdZ9tTmpIDGnQL-ks0oB7zz9vUSUd3G00UZXSYnuhI9BBRXvmmTaue5Y2j5zVZofLdO2dqPWCnsQULyLn_vYf8PeABhnAQ29z1Bq42uxfRFTM35cF40Tp4VBSqXDI1vxfleLusQlOZM-5Sk7O3Vy4Sf-UB03RrRGSBerZjdoMRh7dgEyoYAXS6c4MejCm2vmXKqSd7pu2V2TxOM9UTchkCS16DL-RIJtnfMjznmznU5SoMCpncvs6gRNeQ` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Зашифровать запрос + +Преобразуйте полученный JWS-контейнер алгоритмом **RS256** в соответствии с [JSON Web Encryption](https://datatracker.ietf.org/doc/html/rfc7516) и зашифруйте [открытым ключом](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/encryption/articles/json-rsa/files/cert.cer) сертификата. + +**Формат JWE:** +`BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE Authentication Tag)` + +**Структура заголовка (Protected Header):** + +- `"kid"`: "серийный номер сертификата" +- `"enc"`: "A256GCM" +- `"alg"`: "RSA-OAEP-256" + +**Пример JWE:** +`eyJlbmiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.eFcY1Fv_xN6cFDNxnMoxCjEpVTmAjhrHuB2oW1hYapBXE02qOtdKrC3W7FGVjLFlgV3... (урезано для краткости) ...ZfAY-M8w-t9l9gErE1vQFg` + +### 4. Выполнить запрос + +Необходимо передать специфические HTTP-заголовки: + +- **Без шифрования:** + `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` +- **С шифрованием:** + `Content-Type: application/jose` + `X-Request-ChannelSecurity: ENCRYPTION` + +Банк дешифрует запрос и проверяет подпись. Любые другие комбинации заголовков приведут к ошибке. + +--- + +## Дешифрование и проверка подписи JSON + +### 1. Дешифровать ответ + +Для получения зашифрованного ответа используйте заголовки: +`Accept: application/jose` + `X-Response-ChannelSecurity: ENCRYPTION` + +Необходимо дешифровать ответ с помощью вашего закрытого ключа. + +**Структура JWE (компактная сериализация):** + +1. **Protected Header** (не зашифровано) +2. **Encrypted Key** (зашифровано) +3. **Initialization Vector** (зашифровано) +4. **Ciphertext** (зашифровано) +5. **Authentication Tag** (зашифровано) + +| Закодированный JWE (пример) | Раскодированный (Protected Header) | +| :------------------------------------------------------- | :-------------------------------------------- | +| `eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0...` | `{ "enc": "A256GCM", "alg": "RSA-OAEP-256" }` | + +### 2. Обработать дешифрованный ответ + +После дешифрования JWE вы получите компактную сериализацию **JWS**, состоящую из трех частей: +`Base64URL(Header) . Base64URL(Payload) . Base64URL(Signature)` + +**Пример раскодированного JWS:** + +- **Header:** + ```json + { + "kid": "alfa-test-jwt", + "typ": "JWT", + "alg": "RS256" + } + ``` +- **Payload:** + ```json + { + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } + } + ``` + +### 3. Проверить подпись ответа от Банка + +Используйте [открытый ключ](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/encryption/articles/json-rsa/files/cert.cer) сертификата Банка для проверки подписи. Серийный номер сертификата Банка указан в поле `kid` заголовка JWS. + +### 4. Обработать ответ в формате JSON + +Итоговый результат: + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +**Ссылки для навигации:** + +- ← [Подписание TXT ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/text-gost/text-gost) +- → [Шифрование JSON ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/json-gost/json-gost) diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/get-certificates.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/get-certificates.md new file mode 100644 index 0000000..eba20de --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/get-certificates.md @@ -0,0 +1,103 @@ +# Получение сертификатов + +**Теги:** `B2B` `B2C` `H2H` + +## Эндпоинты + +### Песочница + +`GET https://sandbox.alfabank.ru/api/gd/v1/crypto-service/certificates` + +### Пром + +`GET https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates` + +--- + +## Описание + +Метод позволяет получить информацию по всем сертификатам, выпущенным вне УЦ Альфа-Банка и далее загруженным с помощью метода [«Добавление нового сертификата»](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates). + +> **Внимание** +> Для получения сертификата, выпущенного через сервис [«Электронная подпись»](/products/alfa-api/documentation/articles/signature/signature), используйте метод [«Получение RSA-сертификата»](/products/alfa-api/documentation/articles/signature/articles/get-rsa/v2/get-rsa). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | required | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | required | `application/json` | +| **Content-Type** | `string` | optional | `application/json` | + +### Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обяз. | Описание | +| :------------------- | :------------- | :------- | :--------------------------------------------------------------------------------------------------------- | +| **id** | `string(uuid)` | required | ID сертификата | +| **clientId** | `string(uuid)` | required | Идентификатор партнёрского сервиса | +| **ownerName** | `string` | required | Имя владельца | +| **fingerprint** | `string` | required | Отпечаток сертификата | +| **organizationName** | `string` | optional | Наименование организации | +| **beginDateTime** | `string` | required | Дата начала действия сертификата | +| **expireDateTime** | `string` | required | Дата окончания действия сертификата | +| **status** | `string` | optional | Статус. Возможные значения:
• `ACTIVE` - активен;
• `REVOKED` - аннулирован;
• `DELETED` - удалён | +| **certificateBody** | `string` | required | Тело сертификата в виде base64-строки | +| **type** | `string` | required | Тип сертификата. Возможные значения:
• `SIGNATURE` - для подписи;
• `ENCRYPTION` - для шифрования | +| **algorithm** | `string` | required | Алгоритм сертификата | +| **serialNumber** | `string` | required | Серийный номер сертификата | + +### Пример ответа 200 (OK) + +```json +[ + { + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" + } +] +``` + +--- + +## Ошибки + +| Код | Описание | Возможные значения `error` | +| :------ | :------------- | :------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (настройки scope) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок._ + +--- + +**Навигация:** +[← Добавление нового сертификата](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates) | [Обновление сертификата →](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/patch-certificates/patch-certificates) diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/patch-certificates.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/patch-certificates.md new file mode 100644 index 0000000..726a4c3 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/patch-certificates.md @@ -0,0 +1,131 @@ +# Обновление сертификата + +**Метки:** `B2B` | `B2C` | `H2H` + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :----------------------------------------------------------------------------- | +| **Песочница** | `PATCH https://sandbox.alfabank.ru/api/gd/v1/crypto-service/certificates/{id}` | +| **Пром** | `PATCH https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates/{id}` | + +## Описание + +Метод позволяет отозвать или активировать ранее отозванный сертификат, выпущенный вне УЦ Альфа-Банка. Отозванный сертификат не может использоваться для криптографических операций. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | **Required**. Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | **Required**. `application/json` | +| **Content-Type** | `string` | **Required**. `application/json` | + +### PATH + +| Атрибут | Тип | Описание | +| :------ | :------- | :--------------------------- | +| **id** | `string` | **Required**. ID сертификата | + +### BODY + +| Атрибут | Тип | Описание | +| :-------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- | +| **op** | `string` | **Optional**. Тип операции. Возможные значения: `replace` — замена | +| **path** | `string` | **Optional**. Путь до изменяемого параметра. Возможные значения: `/status` | +| **value** | `string` | **Optional**. Новое значение. Возможные значения:
• `ACTIVE` — сертификат активен;
• `REVOKED` — сертификат аннулирован | + +### Пример запроса + +```bash +curl -X PATCH https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates/{id} \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "op": "replace", + "path": "/status", + "value": "ACTIVE" + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :------------------- | :------------- | :-------------------------------------------------------------------------- | +| **id** | `string(uuid)` | **Required**. ID сертификата | +| **clientId** | `string(uuid)` | **Required**. Идентификатор партнёрского сервиса | +| **ownerName** | `string` | **Required**. Имя владельца | +| **fingerprint** | `string` | **Required**. Отпечаток сертификата | +| **organizationName** | `string` | **Optional**. Наименование организации | +| **beginDateTime** | `string` | **Required**. Дата начала действия сертификата | +| **expireDateTime** | `string` | **Required**. Дата окончания действия сертификата | +| **status** | `string` | **Required**. Статус: `ACTIVE` (активен), `REVOKED` (аннулирован) | +| **certificateBody** | `string` | **Required**. Тело сертификата в виде base64-строки | +| **type** | `string` | **Required**. Тип: `SIGNATURE` (для подписи), `ENCRYPTION` (для шифрования) | +| **algorithm** | `string` | **Required**. Алгоритм сертификата | +| **serialNumber** | `string` | **Required**. Серийный номер сертификата | + +#### Пример ответа 200 + +```json +{ + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBB...", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" +} +``` + +--- + +## Ошибки + +| Код | Описание | Код ошибки (`error`) | +| :------ | :------------- | :------------------------------------------------------------ | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав для вызова сервиса | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | + +### Примеры сообщений об ошибках + +**400 Bad Request** + +```json +{ + "error": "invalid_request", + "error_description": "Authorization header is not present in request headers" +} +``` + +**401 Unauthorized** + +```json +{ + "error": "invalid_token", + "error_description": "The access token provided is expired, revoked, malformed, or invalid for other reasons" +} +``` + +> **Важно:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/post-certificates.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/post-certificates.md new file mode 100644 index 0000000..c63bddd --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/managing-certificates/post-certificates.md @@ -0,0 +1,108 @@ +# Добавление нового сертификата + +**Теги:** `B2B` `B2C` `H2H` + +## Эндпоинты + +### Песочница + +`POST https://sandbox.alfabank.ru/api/gd/v1/crypto-service/certificates` + +### Пром + +`POST https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates` + +## Описание + +Метод позволяет загрузить сертификат, выпущенный вне УЦ Альфа-Банка, для проверки подписи запроса Банком и шифрования ответа от Банка. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/json` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------ | :----- | :------------- | :------------------------------------------------------------------------------------------------------- | +| **type** | string | required | Тип сертификата. Возможные значения:
• `SIGNATURE` — для подписи;
• `ENCRYPTION` — для шифрования. | +| **certificateBody** | string | required | Тело сертификата в виде base64-строки. | + +### Пример запроса + +```bash +curl -X POST https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "type": "ENCRYPTION", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=" + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ: 201 Created + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :----------- | :------------- | :---------------------------------------------------------------------- | +| **id** | string(uuid) | required | ID сертификата | +| **clientId** | string | required | Идентификатор партнёрского сервиса | +| **ownerName** | string | required | Имя владельца | +| **fingerprint** | string | required | Отпечаток сертификата | +| **organizationName** | string | optional | Наименование организации | +| **beginDateTime** | string | required | Дата начала действия сертификата | +| **expireDateTime** | string | required | Дата окончания действия сертификата | +| **status** | string | required | Статус: `ACTIVE` (активен), `REVOKED` (аннулирован), `DELETED` (удалён) | +| **certificateBody** | string | required | Тело сертификата в виде base64-строки | +| **type** | string | required | Тип сертификата (`SIGNATURE` или `ENCRYPTION`) | +| **algorithm** | string | required | Алгоритм сертификата | +| **serialNumber** | string | required | Серийный номер сертификата | + +#### Пример ответа 201 + +```json +{ + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" +} +``` + +--- + +## Ошибки + +| Код | Описание | Код ошибки (в теле) | +| :------ | :-------------------- | :--------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (настройки scope) | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | + +> Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +### Навигация + +← [Для чего это нужно](/products/alfa-api/documentation/articles/signature-encryption/articles/intro/intro) | [Получение сертификатов](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/get-certificates/get-certificates) → diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/signature-encryption-intro.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/signature-encryption-intro.md new file mode 100644 index 0000000..c7c8a70 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/signature-encryption-intro.md @@ -0,0 +1,42 @@ +# Для чего это нужно + +**Теги:** `B2B` `B2C` `H2H` + +Использование транспортной подписи и шифрования с использованием ГОСТ- или RSA-сертификата даёт следующие возможности: + +### **Конфиденциальность** + +Шифрование сообщений обеспечивает защиту данных от посторонних глаз. Это важно, так как в API могут передаваться конфиденциальные данные, такие как номера счетов или личная информация. + +### **Безопасность** + +Подписание сообщений подтверждает подлинность и целостность информации. Если сообщение было изменено или подделано, подпись становится недействительной. + +### **Доверие** + +Подписание и шифрование помогают укрепить доверие между сторонами API, поскольку они подтверждают, что данные не были изменены или подделаны во время передачи. + +### **Соответствие требованиям** + +В некоторых отраслях, таких как финансовые услуги, подписание и шифрование являются обязательными требованиями для соблюдения регуляторных норм и защиты данных. + +### **Аутентификация** + +Подписание сообщения может также использоваться для аутентификации источника данных, тем самым предотвращая фальсификацию или манипуляции с данными. + +--- + +## Навигация по разделу + +- ← [Загрузка файла](/products/alfa-api/documentation/articles/secure-file-transfer/articles/upload/v1/upload) +- → [Добавление нового сертификата](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates) + +--- + +### Справочная информация (из структуры документа) + +Данная статья является частью раздела **Транспортная подпись и шифрование**. В этом разделе также доступны: + +1. [Управление сертификатами для подписи и шифрования](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/managing-certificates) +2. [Транспортная подпись](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/signature) +3. [Шифрование](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/encryption) diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-ghost.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-ghost.md new file mode 100644 index 0000000..b75ded3 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-ghost.md @@ -0,0 +1,105 @@ +# Подписание JSON ГОСТ-сертификатом + +**B2B | B2C | H2H** + +Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке Вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +> **Внимание** +> Для подписания сообщения необходимо предварительно загрузить сертификат, используя следующий [метод](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates). Если Вы уже загружали сертификат, используя данный метод — повторно выполнять эту операцию не нужно. + +## Подписание JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом ГОСТ Р 34.10-2012 256 бит в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса:** + +- **Заголовок (Header)** + - `"alg": "GOST3410_2012_256"` + - `"typ": "JWT"` + - `"cty": "JWS"` + - `"kid": "серийный номер сертификата"` + - `"b64": true` +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS:** + +```text +ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то подпись запроса не будет проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: SIGNATURE` и отправить запрос, то подпись запроса будет проверяться. +- Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. + +Любые другие комбинации заголовков `Content-Type + X-Request-ChannelSecurity` приведут к ошибке. + +--- + +## Проверка подписи JSON + +### 1. Получить ответ + +- Если добавить заголовки `Accept: application/json` + `X-Response-ChannelSecurity: NO`, то ответ не будет подписан. +- Если добавить заголовки `Accept: application/jose` + `X-Response-ChannelSecurity: SIGNATURE`, то полученный ответ (в том числе ошибки) будет подписан и представлен в виде компактной сериализации. + +Любые другие комбинации заголовков `Accept + X-Response-ChannelSecurity` приведут к ошибке. + +**Декодирование компактной сериализации JWS** +JWS формируется из трёх составляющих и представляет структуру вида: + +1. Base64URL(Header); +2. Base64URL(Payload); +3. Base64URL(Signature). + +**Пример JWS:** + +| Закодированный | Раскодированный | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA` | **header** `json { "alg": "GOST3410_2012_256", "typ": "JWT", "cty": "JWS", "kid": "6d38b8e0061b0f9a94f104be57e77aa18", "b64": true } ` **payload** `json { "debitTurnover": { "amount": 0, "currencyName": "RUR" } } ` **verify signature** `text HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), ) ` | + +### 2. Проверить подпись ответа от Банка + +Используйте открытый ключ сертификата Банка для проверки подписи. Для получения сертификата напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +Проверьте подпись в соответствии с данными, указанными в Заголовке (Header). В поле `kid` заголовка JWS будет записан серийный номер сертификата Банка. + +### 3. Обработать ответ в формате JSON + +**Пример ответа:** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +[← Подписание JSON RSA-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-rsa/json-rsa) | [Подписание XML RSA-сертификатом →](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/xml-rsa/xml-rsa) diff --git a/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-rsa.md b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-rsa.md new file mode 100644 index 0000000..0e2ee2f --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/Транспортная_подпись_и_шифрование/transport-signature/json-rsa.md @@ -0,0 +1,104 @@ +# Подписание JSON RSA-сертификатом + +**B2B** | **B2C** | **H2H** + +Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке Вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +> **Внимание** +> Для подписания сообщения необходимо предварительно выпустить сертификат в УЦ Альфа-Банка, используя сервис ["Электронная подпись"](/products/alfa-api/documentation/articles/signature/signature). Если Вы уже выпускали сертификат - повторно выпускать не нужно. + +--- + +## Подписание JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **RS256** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата, выпущенным в сервисе "Электронная подпись". + +**Формат JWS** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса** + +- **Заголовок (Header)** + - `"kid"`: "серийный номер сертификата" + - `"typ"`: "JWT" + - `"alg"`: "RS256" +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS** + +```text +eyJhbGciOiJSUzI1NiIsImtpZCI6IjYxMDAwMzYzY2NiNzU5Y2I0NDg2MDc4NjVkMDAwMTAwMDM2M2NjIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY1Nzg4MjY4OSwiZXhwIjoxNjU3ODg2Mjg5fQ.ApKNzZ9kLMtBY3LzReSHQ7_AyDnzocGo9GTQFRmxTiRS7Lj7a55Kr4ziwZAmmwloF1063JJMOaU0lS947q6_hSct9pxzPdZ9tTmpIDGnQL-ks0oB7zz9vUSUd3G00UZXSYnuhI9BBRXvmmTaue5Y2j5zVZofLdO2dqPWCnsQULyLn_vYf8PeABhnAQ29z1Bq42uxfRFTM35cF40Tp4VBSqXDI1vxfleLusQlOZM-5Sk7O3Vy4Sf-UB03RrRGSBerZjdoMRh7dgEyoYAXS6c4MejCm2vmXKqSd7pu2V2TxOM9UTchkCS16DL-RIJtnfMjznmznU5SoMCpncvs6gRNeQ +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то подпись запроса **не будет** проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: SIGNATURE` и отправить запрос, то подпись запроса **будет** проверяться. + +Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. Любые другие комбинации заголовков `Content-Type + X-Request-ChannelSecurity` приведут к ошибке. + +--- + +## Проверка подписи JSON + +### 1. Получить ответ + +- Если добавить заголовки `Accept: application/json` + `X-Response-ChannelSecurity: NO`, то ответ **не будет** подписан. +- Если добавить заголовки `Accept: application/jose` + `X-Response-ChannelSecurity: SIGNATURE`, то полученный ответ (в том числе ошибки) **будет подписан** и представлен в виде компактной сериализации. + +Любые другие комбинации заголовков `Accept + X-Response-ChannelSecurity` приведут к ошибке. + +**Декодирование компактной сериализации JWS** +JWS формируется из трёх составляющих: + +- Base64URL(Header); +- Base64URL(Payload); +- Base64URL(Signature). + +**Пример JWS** + +| ЗАКОДИРОВАННЫЙ | РАСКОДИРОВАННЫЙ | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.`
`eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.`
`Y1NqCkRjjtJ2GrVsW-a627g6ObfpEaKw-H92QVgVWqL9i7d1SHyaXVghF4ZNZAlrFasKySnKYZf2Ik8zVIlLN7hqeYxoeTdE2OLbiQdvPrD-JnI2Qzh0K32vcImwgGcpq2lt_QKx1f_YmaSRhH9O3xZePVcmFGCqhl_0prQSwcR4g-yuhidvspaF48QlUHcEaZ65Cr8hdyc6g9HPZDy7ipU-zCAZGgK0enxfWn4Osyqch8RRDIsfLG7OJ4wbYwYB22LYO5UaxX8Zy_R2jSnKlNghxQwSqJGxizMFhFhdCrATGTo-ysI-7OtfremD8YNj7z_iYciyYbtAgV0ZodEvMA` | **header**
`{"kid": "alfa-test-jwt", "typ": "JWT", "alg": "RS256"}`

**payload**
`{"debitTurnover": {"amount": 0, "currencyName": "RUR"}}`

**verify signature**
`RSASHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload))` | + +### 2. Проверить подпись ответа от Банка + +Используйте [открытый ключ](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/signature/articles/json-rsa/files/cert.cer) сертификата для проверки подписи. + +Проверьте подпись в соответствии с данными, указанными в Заголовке (Header). В поле `kid` заголовка JWS будет записан серийный номер сертификата Банка. + +### 3. Обработать ответ в формате JSON + +**Пример ответа** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +**← [Обновление сертификата](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/patch-certificates/patch-certificates)** | **[Подписание JSON ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-gost/json-gost) →** diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/get-nominal-accounts.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/get-nominal-accounts.md new file mode 100644 index 0000000..7083605 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/get-nominal-accounts.md @@ -0,0 +1,113 @@ +# Получение списка номинальных счетов + +**H2H** + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :-------------------------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/nominal-accounts` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/nominal-accounts` | + +## Scope + +`beneficiaries` + +## Описание + +Метод позволяет получить список номинальных счетов, зарегистрированных в системе. + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` (required) | application/json | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/nominal-accounts' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 (OK) + +#### Пример ответа + +```json +[ + { + "accountNumber": "40817810306050000000", + "isActive": true + } +] +``` + +#### Тело ответа (BODY) + +| Атрибут | Тип | Описание | +| :---------------- | :------------------- | :------------------------------------------------------------------------------------------------------------- | +| **accountNumber** | `string` (required) | Номер номинального счёта | +| **isActive** | `boolean` (required) | Статус активности номинального счёта. Принимает значения:
• `true` — активен;
• `false` — деактивирован. | + +--- + +### Ошибки + +#### 400 (Bad Request) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `invalid_request` — неверные параметры запроса. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 401 (Unauthorized) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :----------------------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `invalid_token` — токен просрочен, отозван или имеет неверный формат. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 403 (Forbidden) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :--------------------------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `insufficient_scope` — недостаточно прав (несоответствие настроек scope). | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 404 (Not Found) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :-------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 429 (Too Many Requests) + +_Нет тела ответа._ + +#### 500 (Internal Server Error) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :----------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `internal_error` — внутренняя ошибка сервиса. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 503 (Service Unavailable) + +_Нет тела ответа._ + +--- + +## Навигация + +- ← [Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature) +- → [Контрагенты: Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/how-to-encrypt-your-card-number-eg-cardtoken.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/how-to-encrypt-your-card-number-eg-cardtoken.md new file mode 100644 index 0000000..133bba6 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/how-to-encrypt-your-card-number-eg-cardtoken.md @@ -0,0 +1,86 @@ +Вот преобразованный контур документа в формате Markdown. Я сохранил структуру, технические подробности и примеры кода, очистив их от лишней разметки и служебных скриптов. + +--- + +# Номинальные счета / Как зашифровать номер карты + +**H2H** + +## Как зашифровать номер карты + +При проведении выплат по номеру карты в поле `pan` необходимо передавать токен номера карты. Для этого номер карты необходимо зашифровать с помощью алгоритма `RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING`. + +### Примеры шифрования + +#### Python с использованием Crypto.Cipher в PyCryptodome +```python +import sys +from Crypto.Hash import SHA256, SHA1 +from Crypto.PublicKey import RSA +from Crypto.Cipher import PKCS1_OAEP +from base64 import b64decode, b64encode +from Crypto.Signature import pss + +pubkey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwj9k2lFfc/EE2zYdRoRLZF5B42V6n8OHKfxLBLMk/0qpP2ZEYYoCqgbD9xsmLbQMTCxQ8JWj/V08JGpFjuNKJ2hRfRzLUfjTm5ReZJVPDhJa4B0QtUEvCS2R4aMqMpnQ1a1aywGAJoM5ift0apCNGKuZZYrGuFkQXeBw85lSYYNwrVmNUm55RI+tcb' +msg = "4779642610000010" +keyDER = b64decode(pubkey) +keyPub = RSA.importKey(keyDER) +cipher = PKCS1_OAEP.new(keyPub, SHA256, mgfunc=lambda x,y: pss.MGF1(x,y, SHA1)) +cipher_text = cipher.encrypt(msg.encode()) +encodedCard = b64encode(cipher_text) +sys.stdout.buffer.write(encodedCard) +``` + +#### C# с использованием библиотеки Chilkat .NET for the 4.8.* Frameworks +```csharp +Chilkat.Rsa rsa = new Chilkat.Rsa(); +Chilkat.PublicKey pubkey = new Chilkat.PublicKey(); +pubkey.LoadFromFile("C://cardbankkey-sandbox.pub"); +string cardNumber = "4779642610000010"; +rsa.ImportPublicKeyObj(pubkey); +rsa.OaepPadding = true; +rsa.OaepHash = "sha256"; +string encCard = rsa.EncryptStringENC(cardNumber, false); +Console.WriteLine(encCard); +``` + +#### Java с базовыми библиотеками crypto +```java +import lombok.SneakyThrows; +import ru.alfabank.csp.api.decryptor.properties.CryptoServiceProperties; +import javax.crypto.Cipher; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.PublicKey; + +public class CryptoServiceImpl { + private KeyStore keyStore; + private CryptoServiceProperties properties; + + private PublicKey getPublicKey() throws KeyStoreException { + return keyStore.getCertificate(properties.getAlias()).getPublicKey(); + } + + @SneakyThrows + public byte[] encrypt(byte[] data) { + var rsaCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); + rsaCipher.init(Cipher.ENCRYPT_MODE, getPublicKey()); + return rsaCipher.doFinal(data); + } +} +``` + +#### PHP +```php +public function createCypher(string $pan): FunctionResult { + $publicKey = PublicKeyLoader::load(file_get_contents($this->cardBankKey)); + $algo = $publicKey->withPadding(RSA::ENCRYPTION_OAEP)->withHash('sha256')->withMGFHash('sha1'); + return FunctionResult::success(base64_encode($algo->encrypt($pan))); +} +``` + +--- + +### Навигация +* ← [Введение](/products/alfa-api/documentation/articles/nominal-accounts/articles/intro/intro) +* → [Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/intro.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/intro.md new file mode 100644 index 0000000..8aee968 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/intro.md @@ -0,0 +1,50 @@ +# Номинальные счета: Введение + +**Метка документа:** `H2H` + +> **Внимание** +> Для использования сервиса у вас должен быть открыт номинальный счёт в Альфа-Банке. + +Сервис позволяет владельцам номинального счета совершать операции с денежными средствами, права на которые принадлежат другому лицу — бенефициару. + +### Кому подойдёт сервис + +- Финансовым и инвестиционным платформам; +- Маркетплейсам; +- Платформам, работающим с самозанятыми и фрилансерами; +- Для индивидуальных проектов, где требуется обеспечить безопасность проведения расчётов между участниками сделки. + +### Как это работает + +Владелец счёта добавляет сведения о бенефициарах номинального счёта и универсальных реципиентах — [раздел Контрагенты](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro), после чего может совершать операции с денежными средствами номинального счёта: + +- Идентифицировать поступаемые на номинальный счёт денежные средства — раздел [Идентификация пополнений номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/intro/intro). +- Осуществлять выплаты с номинального счёта удобным ему способом: + - [Безопасные сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro): деньги перейдут получателю только после выполнения условий сделки. + - [Прямые выплаты](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/intro/intro): выплаты без создания сделки – с биллингом (например, вывод средств бенефициара или уплата налога за исполнителя), или без биллинга (например, перевод зарегистрированному контрагенту). + +> **Важно** +> Для работы с сервисом необходимо использовать электронную подпись. Допускается использование сертификата, выпущенного с помощью [сервиса Электронная подпись](/products/alfa-api/documentation/articles/signature/articles/intro/intro), или сертификата УКЭП, выпущенного в любом аккредитованном УЦ. Процесс формирования подписи описан [в статье Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature). + +### Термины и определения + +**Номинальный счёт** — это специальный банковский счёт, открытый владельцем номинального счёта для совершения операций с денежными средствами, права на которые принадлежат другому лицу – бенефициару. + +**Владелец номинального счёта (клиент банка)** — лицо, которое открыло номинальный счёт и имеет право распоряжаться денежными средствами, получать информацию о движении денежных средств и закрыть номинальный счёт. + +**Бенефициар** — лицо, которому принадлежат права на денежные средства, находящиеся на номинальном счёте. У одного номинального счёта может быть как один, так и несколько бенефициаров, но каждый из них имеет права только на свою часть денежных средств. + +**Универсальный реципиент** — лицо, которое не является бенефициаром и не имеет права на денежные средства, находящиеся на номинальном счёте. Может выступать только в качестве реципиента (получателя) в безопасных сделках и при выплатах с номинального счёта. + +--- + +### Навигация + +- ← [Получение подписанного реестра](/products/alfa-api/documentation/articles/factoring/articles/documents/v1/documents) +- → [Как зашифровать номер карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) + +--- + +_Медиа-материалы:_ + +- [Видео-презентация сервиса](/assets/developers-portal.docs.alfa-api/articles/nominal-accounts/articles/intro/files/nominal-accounts.mp4) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/signature.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/signature.md new file mode 100644 index 0000000..d1c9c92 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/signature.md @@ -0,0 +1,179 @@ +# Как сформировать подпись + +**H2H** + +### Подписание алгоритмом RSA + +> **Внимание** +> Для подписания необходимо использовать RSA-сертификат, выпущенный с помощью [сервиса Электронная подпись](/products/alfa-api/documentation/articles/signature/signature). + +Для подписания алгоритмом RSA необходимо выполнить следующие шаги: + +#### 1. Подготовьте данные для подписи в формате JSON + +Подписываться должен весь блок данных тела запроса, исключая `digestSignatures`. + +#### 2. Выполните каноникализацию JSON-данных + +Используйте правила [RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785). + +**Пример каноникализированного JSON-сообщения:** + +```json +{ + "company": { "accountNumber": "40702810201400022055" }, + "externalId": "eb19f3ef-ca6a-4f84-a28f-c6e7b469b486", + "requisite": [ + { + "payoutId": "b766f52d-f6e6-4a47-bd71-ab332bd0d314", + "payoutRequisite": { + "byPan": { + "comment": "Курьерские услуги за период с 1.12.2020-20.12.2020", + "pan": "JSv++SDzmKNPIBrLc0G2k3W8lx6DjsHwSFptBCGvUAkq7hVe7KWeACIjjTOAeFKujHQguSIKcqmX93rakldGsTa6c5iZTEAsyhBp5dcPLti8F9x90iXNvCUgvPEXGclqBNvTCuVGaNbmAWrGbogHTn4LKmxxrmzeMIL+e51/YFdTpTnJ384xhiYzAzX4XxFY2CsgNOlyN5xCesOjgeYz+UBlW0MCcY9c8AJBh7+DwU09+zlS0GNtpti7GoETeQrjUv6aPqqu2IMGfO116/xVheUdwLNhcDCT2uvbRpmk9B7pMuLuekGhaA1odvoTghjvY1d1RWnjyO4ZrHpBMpVesg==" + }, + "payoutTotalAmount": "24.00", + "payoutType": "CARD" + }, + "selfemployed": { + "name": "Диогенович", + "patronymic": "Камень", + "surname": "Безукоризненный" + } + } + ] +} +``` + +#### 3. Сформируйте контейнер электронной подписи в формате PKCS#7 (CMS) + +Контейнер в виде структуры `ContentInfo` должен соответствовать стандарту [RFC 5652](https://www.ietf.org/rfc/rfc5652.txt). + +Для создания структуры, вычисления хэша и подписи используйте криптографические провайдеры (например, Bouncy Castle или OpenSSL). + +**Технические требования:** + +1. **Тип:** Рекомендуется присоединённая подпись. +2. **Формат:** [RFC 5652](https://www.ietf.org/rfc/rfc5652.txt) (PKCS#7/CMS). +3. **Алгоритм хэш-функции:** SHA-256 (OID 2.16.840.1.101.3.4.2.1). +4. **Алгоритм подписи:** `sha256WithRSAEncryption`. + +Структура `SignedData`: + +```asn1 +SignedData ::= SEQUENCE { + version CMSVersion, + digestAlgorithms DigestAlgorithmIdentifiers, + encapContent Info EncapsulatedContentInfo, + certificates [0] IMPLICIT CertificateSet OPTIONAL, + crls [1] IMPLICIT Revocation InfoChoices OPTIONAL, + signerInfos SignerInfos +} +``` + +Структура `SignerInfo`: + +```asn1 +SignerInfo ::= SEQUENCE { + version CMSVersion, + sid SignerIdentifier, + digestAlgorithm DigestAlgorithmIdentifier, + signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, + signatureAlgorithm SignatureAlgorithmIdentifier, + signature SignatureValue, + unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL +} +``` + +**Обязательные атрибуты в `signedAttrs`:** + +- ContentType = OID 1.2.840.113549.1.7.1 +- SigningTime = OID 1.2.840.113549.1.9.5 +- CMSAlgorithmProtection = OID 1.2.840.113549.1.9.52 (RFC 6211) +- messageDigest = OID 1.2.840.113549.1.9.4 + +_Примечание: Атрибут `unsignedAttrs` не используется._ + +#### 4. Закодируйте контейнер и передайте подпись в запросе + +Полученный PKCS#7-контейнер закодируйте в `base64` и передайте в параметре `base64Encoded` массива `digestSignatures` в теле запроса. + +--- + +### Примеры кода + +#### Пример формирования подписи на Java + +```java +@Override +public RsaSignResponse sign(RsaSignRequest request) throws Exception { + Security.addProvider(new BouncyCastleProvider()); + BouncyCastleProvider provider = (BouncyCastleProvider) Security.getProvider("BC"); + PrivateKey key = (PrivateKey) keyStore.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray()); + X509Certificate cert = (X509Certificate) keyStore.getCertificate(KEYSTORE_ALIAS); + CMSTypedData msg = new CMSProcessableByteArray(request.getDataToSign().getBytes()); + CMSSignedDataGenerator signedDataGen = new CMSSignedDataGenerator(); + X509CertificateHolder signCert = new X509CertificateHolder(cert.getEncoded()); + ContentSigner signer = new JcaContentSignerBuilder("sha256WithRSAEncryption") + .setProvider(provider) + .build(key); + signedDataGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder( + new JcaDigestCalculatorProviderBuilder().setProvider(provider).build() + ).setDirectSignature(true).build(signer, signCert)); + // добавляем сертификат в подпись + JcaCertStore certs = new JcaCertStore(Collections.singletonList(cert)); + signedDataGen.addCertificates(certs); + CMSSignedData signedData = signedDataGen.generate(msg, true); + byte[] signatureBytes = signedData.getEncoded("DER"); + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + byte[] hashedString = messageDigest.digest(request.getDataToSign().getBytes()); + return new RsaSignResponse() + .base64Encoded(new String(Base64.getEncoder().encode(signatureBytes))); +} +``` + +#### Пример формирования подписи на PHP + +```php +public function sign(string $data, string $password = null): string +{ + $key = file_get_contents($this->private_key); + $cert = file_get_contents($this->certificate); + $privateKey = openssl_pkey_get_private($key, $password ?: $this->private_key_password); + $certid = openssl_x509_read($cert); + $inputTmpFile = tmpfile(); + fwrite($inputTmpFile, $data); + fseek($inputTmpFile, 0); + $outputTmpFile = tmpfile(); + openssl_pkcs7_sign( + stream_get_meta_data($inputTmpFile)['uri'], + stream_get_meta_data($outputTmpFile)['uri'], + $certid, + $privateKey, + [], + PKCS7_ATTACHED + ); + fseek($outputTmpFile, 0); + $signature = fread($outputTmpFile, filesize(stream_get_meta_data($outputTmpFile)['uri'])); + $signature = trim(explode("\n\n", $signature, 2)[1]); + fclose($inputTmpFile); + fclose($outputTmpFile); + return str_replace("\n", '', $signature); +} +``` + +--- + +### Подписание алгоритмом ГОСТ с использованием сертификата УКЭП + +Для подписания может использоваться сертификат УКЭП, выпущенный любым аккредитованным УЦ. Если сертификат выдан уполномоченному лицу (не руководителю по уставу), дополнительно потребуется машиночитаемая доверенность (МЧД). + +1. Сформируйте электронную подпись с использованием криптопровайдера **КриптоПро CSP**. +2. Закодируйте полученное значение **отсоединённой** электронной подписи в формат `base64`. +3. Передайте значение в параметре `base64Encoded` массива `digestSignatures`. + +--- + +**Навигация:** + +- [Как зашифровать номер карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) +- [Получение списка номинальных счетов](/products/alfa-api/documentation/articles/nominal-accounts/articles/get-accounts/v1/get-accounts) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-deal.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-deal.md new file mode 100644 index 0000000..907cf40 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-deal.md @@ -0,0 +1,106 @@ +# Регистрация сделки + +**Тип интеграции:** H2H + +## Эндпоинты + +- **Песочница:** `POST https://sandbox.alfabank.ru/api/na/jp/v1/deals` +- **Пром:** `POST https://baas.alfabank.ru/api/na/jp/v1/deals` + +## Scope + +`deals` + +## Описание + +Метод позволяет зарегистрировать новую сделку в статусе `DRAFT`. + +> **Важно:** Для создания сделки необходимо наличие открытого номинального счёта в Банке. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :----- | :------------- | :----------------------------------------------- | +| **accountNumber** | string | required | Номер номинального счёта | +| **expireDate** | string | required | Дата истечения сделки | +| **digestSignatures** | array | required | Электронная подпись УЛ клиента (массив объектов) | +| — **base64Encoded** | string | required | Значение электронной подписи в Base64 | +| — **signatureType** | string | required | Тип подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/deals' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accountNumber": "40817810306050000000", + "expireDate": "2032-03-02", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :------ | :------------- | :--------------------------------------------- | +| **dealId** | string | required | Идентификатор сделки | +| **status** | string | required | Статус сделки: `DRAFT` (принята для обработки) | +| **expireDate** | string | required | Дата истечения сделки | +| **isValid** | boolean | required | Флаг валидности сделки | + +**Пример JSON:** + +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "DRAFT", + "expireDate": "2032-03-02", + "isValid": false +} +``` + +--- + +## Коды ошибок + +| Код | Ошибка | Описание | +| :------ | :------------------- | :------------------------------------------------------------ | +| **400** | `invalid_request` | Неверные входные параметры запроса | +| **401** | `invalid_token` | Токен просрочен, отозван или недействителен | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (ошибка в настройках scope) | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | — | Слишком много запросов (Too Many Requests) | +| **500** | `internal_error` | Внутренняя ошибка сервиса | +| **503** | — | Сервис временно недоступен | + +--- + +**Навигация:** + +- [← Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro) +- [Получение списка сделок →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deals/v1/get-deals) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-step.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-step.md new file mode 100644 index 0000000..428adb5 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/add-step.md @@ -0,0 +1,136 @@ +# Выполнение действия по этапам сделки + +tags: `H2H` + +### Эндпоинты + +- **Песочница:** `POST https://sandbox.alfabank.ru/api/na/jp/v1/deals/steps` +- **Пром:** `POST https://baas.alfabank.ru/api/na/jp/v1/deals/steps` + +### Scope + +`deals` + +### Описание + +> **Важно** +> +> - Создание этапа сделки происходит в синхронном режиме. +> - Завершение этапа сделки происходит в асинхронном режиме. + +Метод позволяет создать и завершить этап сделки. + +#### Создание этапа сделки + +После [регистрации сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal) необходимо создать этапы сделки для совершения финансовых операций. Этап сделки можно создать только для сделок в статусе `DRAFT`. + +- Если сделка предполагает совершение переводов денежных средств одновременно всем реципиентам, то достаточно создать один этап сделки. +- Если переводы денежных средств должны совершаться последовательно в несколько этапов, то следует создать соответствующее количество этапов сделки. + +#### Завершение этапа сделки + +При наступлении момента проведения расчётов по этапу сделки необходимо инициировать завершение этапа сделки. При завершении этапа сделки происходят все финансовые операции между участниками этапа сделки, и он переходит в статус `COMPLETED`. + +- Если при [добавлении реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors) в этап сделки был проставлен признак `keepOnNominalAccount = false`, то денежные средства переводятся с захолдированного кошелька депонента на основной и налоговый кошельки реципиента, холдируются там, а затем производится выплата по реквизитам реципиента с номинального счёта. +- Если был проставлен признак `keepOnNominalAccount = true`, то денежные средства переводятся на кошельки реципиента внутри системы без фактического перевода с номинального счёта. + +Завершить этап сделки можно только после [подтверждения сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). + +--- + +### Параметры запроса + +#### Headers + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :------------- | +| **Authorization** | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | string | required | +| **Accept** | application/json | string | required | +| **Content-Type** | application/json | string | required | + +#### Body + +| Атрибут | Описание | Тип | Обязательность | +| :------------------- | :------------------------------------------------------------------- | :--------------- | :------------- | +| **dealId** | Идентификатор сделки | string | required | +| **stepId** | Идентификатор этапа сделки | string | optional | +| **action** | Действие по этапу сделки: `CREATE` (создать), `COMPLETE` (завершить) | string | required | +| **description** | Описание этапа сделки (при создании) | string | optional | +| **digestSignatures** | Массив объектов: Электронная подпись УЛ клиента | array of objects | required | +| └ **base64Encoded** | Значение электронной подписи в Base64 | string | required | +| └ **signatureType** | Тип подписи: `rsa` или `kep` | string | required | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/deals/steps' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "action": "CREATE", + "description": "Этап 1", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +#### Успешное создание (200 OK) + +| Атрибут | Описание | Тип | +| :-------------- | :------------------------- | :------ | +| **dealId** | Идентификатор сделки | string | +| **stepId** | Идентификатор этапа сделки | string | +| **stepNumber** | Порядковый номер этапа | integer | +| **description** | Описание этапа | string | + +**Пример ответа 200:** + +```json +{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepNumber": 1, + "description": "Этап 1" +} +``` + +#### Запрос принят (202 Accepted) — при завершении этапа + +| Атрибут | Описание | Тип | +| :------------ | :----------------------------------------------------------------------------------------------- | :----- | +| **status** | Статус запроса: `FAILED`, `TIMEOUT`, `PENDING`, `PAYMENT_FAILED`, `TRANSFER_FAILED`, `COMPLETED` | string | +| **requestId** | Идентификатор запроса | string | + +--- + +### Ошибки + +| Код | Описание (error / error_description) | +| :-------------------------- | :------------------------------------------------------- | +| **400 Bad Request** | `invalid_request` — неверные входные параметры | +| **401 Unauthorized** | `invalid_token` — токен просрочен или недействителен | +| **403 Forbidden** | `insufficient_scope` — нет прав на использование сервиса | +| **404 Not Found** | `unknown_endpoint` — эндпоинт не найден | +| **429 Too Many Requests** | Превышен лимит запросов (тело ответа отсутствует) | +| **500 Internal Error** | `internal_error` — внутренняя ошибка сервиса | +| **503 Service Unavailable** | Сервис недоступен (тело ответа отсутствует) | + +--- + +**Навигация:** + +- Предыдущий раздел: [Выполнение действия по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions) +- Следующий раздел: [Получение статуса запроса на завершение этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-actions.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-actions.md new file mode 100644 index 0000000..d3f4307 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-actions.md @@ -0,0 +1,126 @@ +# Выполнение действия по сделке + +tags: **H2H** + +### Эндпоинты + +- **Песочница:** `PATCH https://sandbox.alfabank.ru/api/na/jp/v1/deals/action` +- **Пром:** `PATCH https://baas.alfabank.ru/api/na/jp/v1/deals/action` + +--- + +### Scope + +`deals` + +### Описание + +Метод позволяет подтвердить, отменить или завершить сделку. + +#### Подтверждение сделки + +При успешном подтверждении сделки денежные средства депонентов холдируются в сумме, необходимой для проведения расчётов в рамках текущей сделки для каждого этапа сделки, и сделка переходит из статуса `DRAFT` в статус `ACTIVE`. + +#### Отмена сделки + +При успешной отмене сделки ранее захолдированные денежные средства депонентов расхолдируются и становятся доступны для использования в расчётах (если сделка была ранее подтверждена), и сделка переходит в статус `CLOSED`. + +#### Завершение сделки + +При успешном завершении сделка переходит в статус `COMPLETED`. + +> **Важно** +> Завершить сделку можно, только если все [этапы сделки завершены](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Описание | +| :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization**
_string, required_ | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
_string, required_ | application/json | +| **Content-Type**
_string, required_ | application/json | + +#### BODY + +| Атрибут | Описание | +| :----------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **dealId**
_string, required_ | Идентификатор сделки | +| **action**
_string, required_ | Действие по сделке. Возможные значения: | +| **digestSignatures**
_array of objects, required_ | Электронная подпись УЛ клиента | +| **└ base64Encoded**
_string, required_ | Значение электронной подписи, закодированное в Base64 | +| **└ signatureType**
_string, required_ | Тип электронной подписи. Возможные значения: | + +--- + +### Пример запроса + +```bash +curl --location --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/action' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "action": "ACCEPT", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +**204 No Content** +_Нет тела ответа_ + +**400 Bad Request** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description**
_string, optional_ | Описание ошибки | + +**401 Unauthorized** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `invalid_token` — токен просрочен, отозван или недействителен | +| **error_description**
_string, optional_ | Описание ошибки | + +**403 Forbidden** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `insufficient_scope` — нет прав на использование сервиса (настройки scope) | +| **error_description**
_string, optional_ | Описание ошибки | + +**404 Not Found** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `unknown_endpoint` — эндпоинт не найден или неактивен | +| **error_description**
_string, optional_ | Описание ошибки | + +**429 Too Many Requests** +_Нет тела ответа_ + +**500 Internal Server Error** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description**
_string, optional_ | Описание ошибки | + +**503 Service Unavailable** +_Нет тела ответа_ + +--- + +### Навигация + +- [← Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) +- [Выполнение действия по этапам сделки →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-is-valid.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-is-valid.md new file mode 100644 index 0000000..ce18ed5 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/deal-is-valid.md @@ -0,0 +1,97 @@ +# Проверка возможности осуществления выплат по сделке + +tags: `H2H` + +## Эндпоинты + +**Песочница** +`PATCH https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/is-valid` + +**Пром** +`PATCH https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/is-valid` + +## Scope + +`deals` + +## Описание + +Метод позволяет проверить возможность осуществления платежей по сделке по `dealId`: + +- проверяет правильность формирования сделки; +- проверяет балансы бенефициаров; +- сверяет суммы участников сделки. + +> **Важно** +> Проверка доступна только для сделок в статусе `DRAFT`. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string (required) | application/json | + +### PATH + +| Атрибут | Тип | Описание | +| :--------- | :---------------- | :------------------- | +| **dealId** | string (required) | Идентификатор сделки | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/is-valid' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK + +**Пример ответа:** + +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "isValid": true, + "description": [ + "Неверная сумма депонированных средств по этапу сделки ab9cbb96-360a-4462-a683-955cc29f7f54;" + ] +} +``` + +**Структура тела (BODY):** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **dealId** | string (required) | Идентификатор сделки | +| **isValid** | boolean (required) | Результат прохождения проверки: `true` — сделка прошла валидацию; `false` — сделка не прошла валидацию. | +| **description** | array of strings (optional) | Описание ошибок. Возвращается при неудачном прохождении валидации. | + +--- + +### Коды ошибок + +| Код | Описание | Атрибуты ответа | +| :------ | :------------------ | :-------------------------------------------------------------------------- | +| **400** | Bad Request | `error`: `invalid_request` — неверные входные параметры запроса. | +| **401** | Unauthorized | `error`: `invalid_token` — токен просрочен, отозван или недействителен. | +| **403** | Forbidden | `error`: `insufficient_scope` — недостаточно прав на использование сервиса. | +| **404** | Not Found | `error`: `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **429** | Too Many Requests | Нет тела ответа. | +| **500** | Internal Error | `error`: `internal_error` — внутренняя ошибка сервиса. | +| **503** | Service Unavailable | Нет тела ответа. | + +--- + +## Навигация + +- **Назад:** [Получение информации о сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal/v1/get-deal) +- **Вперед:** [Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-contractors.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-contractors.md new file mode 100644 index 0000000..25fc6f9 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-contractors.md @@ -0,0 +1,105 @@ +# Получение информации об участниках этапа сделки + +tags: `H2H` + +Метод позволяет получить информацию об участниках этапа сделки по `dealId` и `stepId`. + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :--------------------------------------------------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}/contractors` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}/contractors` | + +**Scope:** `deals` + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :------------- | +| **Authorization** | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | string | required | +| **Accept** | application/json | string | required | + +### QUERY + +| Атрибут | Описание | Тип | Обязательность | +| :--------------- | :----------------------------------------------------------------------------------------------------------- | :----- | :------------- | +| **contractorId** | Идентификатор участника сделки | string | optional | +| **role** | Роль участника этапа сделки. Возможные значения:
• `DEPONENT` — плательщик;
• `RECIPIENT` — получатель | string | optional | + +### PATH + +| Атрибут | Описание | Тип | Обязательность | +| :--------- | :------------------------- | :----- | :------------- | +| **dealId** | Идентификатор сделки | string | required | +| **stepId** | Идентификатор этапа сделки | string | required | + +--- + +## Пример запроса + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}/contractors?contractorId=ab9cbb96-360a-4462-a683-955cc29f7f54&role={role}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Пример ответа 200 (OK) + +```json +[ + { + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "role": "DEPONENT", + "amount": "10.00", + "purpose": "Назначение платежа", + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "keepOnNominalAccount": true, + "amounts": [ + { + "walletType": "MAIN", + "amount": "10.00" + } + ] + } +] +``` + +### BODY (Успешный ответ) + +| Атрибут | Описание | Тип | Обязательность | +| :----------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :------------- | +| **beneficiaryId** | Идентификатор бенефициара или универсального реципиента | string | optional | +| **role** | Роль участника этапа сделки: `DEPONENT` (плательщик), `RECIPIENT` (получатель) | string | optional | +| **amount** | Сумма депонирования в рублях | string | optional | +| **purpose** | Назначение платежа реципиента | string | optional | +| **requisiteId** | Идентификатор платёжного реквизита реципиента | string | optional | +| **keepOnNominalAccount** | Признак вывода денег на виртуальный счёт:
• `true` — оставить в рамках номинального счёта;
• `false` — вывести по ID реквизита | boolean | optional | +| **amounts** | Массив объектов: Суммы реципиента | array of objects | optional | + +**Вложенные поля `amounts`:** + +- **walletType** (string, optional): Тип суммы (`MAIN` — основная, `TAX` — налоговая). +- **amount** (string, optional): Сумма в рублях. + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :------ | :------------------ | :------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-payoffs.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-payoffs.md new file mode 100644 index 0000000..a3aa811 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-payoffs.md @@ -0,0 +1,94 @@ +# Получение списка платежей по сделке + +tags: `H2H` + +Метод позволяет получить список выплат по сделке по идентификатору `dealId`. + +## Эндпоинты + +- **Песочница:** `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/payoffs` +- **Пром:** `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/payoffs` + +## Scope + +`deals` + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :----- | :------------- | :------------------- | +| **dealId** | string | required | Идентификатор сделки | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/payoffs' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа (200 OK) + +### BODY (JSON) + +| Атрибут | Тип | Обязательность | Описание | +| :-------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **stepId** | string | required | Идентификатор этапа сделки | +| **payoffId** | string | required | Идентификатор платежа | +| **payoffType** | string | required | Тип платежа:
• `EXTERNAL` — внешний (выплата с номинального счёта)
• `INTERNAL` — внутренний (выплата внутри номинального счёта) | +| **deponentId** | string | required | Идентификатор депонента | +| **recipientId** | string | required | Идентификатор реципиента | +| **amount** | string | required | Сумма в рублях | +| **status** | string | required | Статус запроса:
• `PENDING` — запрос в процессе обработки
• `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения запроса-дубля
• `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа
• `FAILED` — ошибка обработки
• `FAILED_DUPLICATE` — дубль отклонен
• `COMPLETE` — успешно завершено | + +### Пример ответа 200 + +```json +[ + { + "stepId": "f099f9dd-d5e7-4ab3-89f5-24932aa808ad", + "payoffId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "payoffType": "EXTERNAL", + "deponentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "recipientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "100.00", + "status": "PENDING" + } +] +``` + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (основные атрибуты) | +| :------ | :------------------ | :---------------------------------------------------- | +| **400** | Bad Request | `error`: `invalid_request` — неверные параметры | +| **401** | Unauthorized | `error`: `invalid_token` — токен недействителен | +| **403** | Forbidden | `error`: `insufficient_scope` — нет прав доступа | +| **404** | Not Found | `error`: `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `error`: `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** + +- Предыдущий метод: [Проверка возможности осуществления выплат по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-is-valid/v1/deal-is-valid) +- Следующий метод: [Выполнение действия по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-request-status.md new file mode 100644 index 0000000..b64df6a --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal-request-status.md @@ -0,0 +1,116 @@ +# Получение статуса запроса на завершение этапа сделки + +tags: **H2H** + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :---------------------------------------------------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/requests/{requestId}/status` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/requests/{requestId}/status` | + +## Scope + +`deals` + +## Описание + +Метод позволяет получить статус запроса на завершение этапа сделки по `requestId`. + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :------------ | :----- | :------------- | :-------------------- | +| **dealId** | string | required | Идентификатор сделки | +| **requestId** | string | required | Идентификатор запроса | + +## Пример запроса + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/requests/{requestId}/status' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +## Параметры ответа + +### 200 (OK) + +**Пример тела ответа:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +**Описание полей (BODY):** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **requestId** | string | required | Идентификатор запроса | +| **status** | string | required | Статус запроса. Возможные значения: +`FAILED` — ошибка обработки; +`TIMEOUT` — превышено время ожидания; +`PENDING` — в процессе обработки; +`PAYMENT_FAILED` — неудача внешнего платежа; +`TRANSFER_FAILED` — неудача внутреннего платежа (внутри НС); +`COMPLETED` — успешно завершено. | +| **description** | string | optional | Описание причины, по которой запрос завершился неудачей. Возвращается, если статус равен `FAILED`. | + +--- + +### Ошибки + +#### 400 Bad Request + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :----------------------------------------------------- | +| **error** | string | `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | Описание ошибки | + +#### 401 Unauthorized + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :------------------------------------------------------------ | +| **error** | string | `invalid_token` — токен просрочен, отозван или недействителен | +| **error_description** | string | Описание ошибки | + +#### 403 Forbidden + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :----------------------------------------------------------------------------- | +| **error** | string | `insufficient_scope` — нет прав на использование сервиса (недостаточный scope) | +| **error_description** | string | Описание ошибки | + +#### 404 Not Found + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :---------------------------------------------------- | +| **error** | string | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **error_description** | string | Описание ошибки | + +#### 429 Too Many Requests + +Нет тела ответа. Превышен лимит запросов. + +#### 500 Internal Server Error + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :------------------------------------------- | +| **error** | string | `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | Описание ошибки | + +#### 503 Service Unavailable + +Нет тела ответа. Сервис временно недоступен. diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal.md new file mode 100644 index 0000000..9a9b175 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deal.md @@ -0,0 +1,100 @@ +Приношу извинения, в предыдущем ответе могли проскочить остаточные элементы структуры. Вот полностью очищенный от HTML-тегов, спецсимволов и лишней разметки текст в формате Markdown. + +--- + +# Получение информации о сделке + +**Тип интеграции:** H2H +**Scope:** `deals` + +## Эндпоинты + +* **Песочница:** `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}` +* **Пром:** `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}` + +## Описание +Метод позволяет получить детальную информацию о сделке по идентификатору `dealId`. + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| Authorization | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| Accept | string | Да | application/json | + +### PATH +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| dealId | string | Да | Идентификатор сделки | + +## Пример запроса + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа (200 OK) + +### Пример тела ответа +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "DRAFT", + "expireDate": "2032-03-02", + "isValid": false, + "steps": [ + { + "id": "f099f9dd-d5e7-4ab3-89f5-24932aa808ad", + "description": "Этап 1", + "stepNumber": 1, + "status": "NEW", + "isValid": false + } + ] +} +``` + +### Структура ответа (BODY) + +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **dealId** | string | Да | Идентификатор сделки | +| **status** | string | Да | Статус сделки. Возможные значения: `DRAFT` (принята), `ACTIVE` (успешно обработана), `BLOCKED` (ошибка обработки), `PAYMENT_FAILED` (ошибка платежа), `CLOSED` (отменена), `COMPLETED` (успешно завершена) | +| **expireDate** | string | Да | Дата истечения сделки | +| **isValid** | boolean | Да | Флаг валидности сделки | +| **steps** | array | Нет | Данные об этапах сделки (список объектов) | + +### Параметры этапа сделки (внутри массива steps) + +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **id** | string | Да | Идентификатор этапа | +| **description** | string | Да | Описание этапа | +| **stepNumber** | integer | Да | Порядковый номер этапа | +| **status** | string | Да | Статус этапа: `NEW` (принят), `IN_PROGRESS` (в обработке), `PAYMENT_FAILED` (ошибка платежа), `COMPLETED` (завершен) | +| **isValid** | string | Да | Флаг валидности этапа | + +--- + +## Коды ответов и ошибок + +| Код | Описание | Значение error / error_description | +| :--- | :--- | :--- | +| **200** | OK | Успешное получение информации | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или неверный формат | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (проверьте scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Превышено количество запросов (без тела ответа) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Сервис временно недоступен (без тела ответа) | + +--- +**Навигация:** +[← Получение списка сделок](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deals/v1/get-deals) | [Проверка возможности выплат →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-is-valid/v1/deal-is-valid) + diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deals.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deals.md new file mode 100644 index 0000000..11550c1 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-deals.md @@ -0,0 +1,111 @@ +# Получение списка сделок +**H2H** + +Метод позволяет получить список всех сделок (независимо от статуса) по номинальному счёту с момента его открытия. + +## Эндпоинты + +| Окружение | Метод | URL | +| :--- | :--- | :--- | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/na/jp/v1/deals` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/na/jp/v1/deals` | + +**Scope:** `deals` + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | + +### QUERY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **accountNumber** | string | required | Номер номинального счёта | +| **limit** | integer | optional | Количество объектов на одной странице | +| **offset** | integer | optional | Количество объектов в списке, которые необходимо пропустить | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals?accountNumber={accountNumber}&limit=100&offset={offset}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK +Пример тела ответа: +```json +{ + "pagination": { + "limit": 100, + "offset": 0, + "totalCount": 1 + }, + "deals": [ + { + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "DRAFT", + "expireDate": "2032-03-02", + "isValid": false, + "steps": [ + { + "id": "f099f9dd-d5e7-4ab3-89f5-24932aa808ad", + "description": "Этап 1", + "stepNumber": 1, + "status": "NEW", + "isValid": false + } + ] + } + ] +} +``` + +#### Описание полей ответа (200 OK) + +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **pagination** | object | optional | Данные пагинации | +| ∟ **limit** | number | optional | Количество записей на одной странице | +| ∟ **offset** | number | optional | Количество записей в списке, которые были пропущены | +| ∟ **totalCount** | number | optional | Общее количество записей | +| **deals** | array | optional | Данные о сделках | +| ∟ **dealId** | string | required | Идентификатор сделки | +| ∟ **status** | string | required | Статус сделки: `DRAFT`, `ACTIVE`, `BLOCKED`, `PAYMENT_FAILED`, `CLOSED`, `COMPLETED` | +| ∟ **expireDate** | string | required | Дата истечения сделки | +| ∟ **isValid** | boolean | required | Флаг валидности сделки | +| ∟ **steps** | array | optional | Данные об этапах сделки | +| ∟ ∟ **id** | string | required | Идентификатор этапа сделки | +| ∟ ∟ **description** | string | required | Описание этапа сделки | +| ∟ ∟ **stepNumber** | integer | required | Порядковый номер этапа сделки | +| ∟ ∟ **status** | string | required | Статус этапа: `NEW`, `IN_PROGRESS`, `PAYMENT_FAILED`, `COMPLETED` | +| ∟ ∟ **isValid** | boolean | required | Флаг валидности этапа сделки | + +--- + +## Ошибки + +| Код | Описание (error) | error_description | +| :--- | :--- | :--- | +| **400** | `invalid_request` | Неверные входные параметры запроса | +| **401** | `invalid_token` | Токен просрочен, отозван или имеет неправильный формат | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (настройки scope) | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | — | Слишком много запросов (нет тела ответа) | +| **500** | `internal_error` | Внутренняя ошибка сервиса | +| **503** | — | Сервис недоступен (нет тела ответа) | + +--- +**Навигация:** +[← Регистрация сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal) | [Получение информации о сделке →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal/v1/get-deal) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-step.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-step.md new file mode 100644 index 0000000..470c1c9 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-step.md @@ -0,0 +1,98 @@ +# Получение информации об этапе сделки + +**Тип интеграции:** H2H +**Scope:** `deals` + +Метод позволяет получить детальную информацию об этапе сделки по `dealId` и `stepId`. + +--- + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :--------------------------------------------------------------------------- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}` | + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | + +### PATH (Путь) + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :----- | :------------- | :------------------------- | +| **dealId** | string | required | Идентификатор сделки | +| **stepId** | string | required | Идентификатор этапа сделки | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Пример тела ответа:** + +```json +{ + "stepId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "stepNumber": 1, + "description": "Этап 1", + "status": "DRAFT", + "isValid": false +} +``` + +**Описание полей:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **stepId** | string | required | Идентификатор этапа сделки | +| **stepNumber** | integer | required | Порядковый номер этапа сделки | +| **description** | string | required | Описание этапа сделки | +| **status** | string | required | Статус этапа сделки (см. ниже) | +| **isValid** | boolean | required | Флаг валидности этапа сделки | + +#### Возможные значения статуса (`status`): + +- `DRAFT` — принят для последующей обработки; +- `ACTIVE` — успешно обработан; +- `BLOCKED` — ошибка в процессе обработки; +- `IN_PROGRESS` — в процессе обработки; +- `PAYMENT_FAILED` — платёж завершился неудачей; +- `CLOSED` — отменен; +- `COMPLETED` — успешно завершен. + +--- + +## Ошибки + +| Код | Описание (error) | Детали (error_description) | +| :------ | :------------------- | :-------------------------------------------- | +| **400** | `invalid_request` | Неверные входные параметры запроса | +| **401** | `invalid_token` | Токен просрочен, отозван или недействителен | +| **403** | `insufficient_scope` | У пользователя нет прав (недостаточный scope) | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | — | Слишком много запросов (нет тела ответа) | +| **500** | `internal_error` | Внутренняя ошибка сервиса | +| **503** | — | Сервис недоступен (нет тела ответа) | + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-steps.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-steps.md new file mode 100644 index 0000000..f57a5fe --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/get-steps.md @@ -0,0 +1,98 @@ +# Получение списка этапов сделки + +**Тип интеграции:** H2H +**Scope:** `deals` + +Метод позволяет получить список этапов сделки по `dealId`. + +--- + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :------------------------------------------------------------------ | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps` | + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string (required) | `application/json` | + +### QUERY + +| Атрибут | Тип | Описание | +| :--------- | :----------------- | :--------------------------------------------------------------------------------------- | +| **offset** | integer (optional) | Количество элементов в списке, которое необходимо пропустить. Значение по умолчанию: `0` | +| **limit** | integer (optional) | Количество элементов в списке, которое необходимо вывести. Значение по умолчанию: `50` | + +### PATH + +| Атрибут | Тип | Описание | +| :--------- | :---------------- | :------------------- | +| **dealId** | string (required) | Идентификатор сделки | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps?offset={offset}&limit={limit}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Пример ответа 200 (OK) + +```json +[ + { + "stepId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "stepNumber": 1, + "description": "Этап 1", + "status": "DRAFT", + "isValid": false + } +] +``` + +### BODY (200 OK) + +| Атрибут | Тип | Описание | +| :-------------- | :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **stepId** | string (required) | Идентификатор этапа сделки | +| **stepNumber** | integer (required) | Порядковый номер этапа сделки | +| **description** | string (required) | Описание этапа сделки | +| **status** | string (required) | Статус этапа сделки. Возможные значения:
• `DRAFT` — принят для последующей обработки;
• `ACTIVE` — успешно обработан;
• `BLOCKED` — ошибка в процессе обработки;
• `IN_PROGRESS` — в процессе обработки;
• `PAYMENT_FAILED` — платёж завершился неудачей;
• `CLOSED` — отменен;
• `COMPLETED` — успешно завершен | +| **isValid** | boolean (required) | Флаг валидности этапа сделки | + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :-------------------- | :----------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** + +- Предыдущий метод: [Получение статуса запроса на завершение этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status) +- Следующий метод: [Получение информации об этапе сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-step/v1/get-step) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/intro.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/intro.md new file mode 100644 index 0000000..493ef4d --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/intro.md @@ -0,0 +1,87 @@ +# Как это работает + +**Теги:** H2H + +> **Примечание** +> Депонент — это участник сделки, который выступает в качестве плательщика, реципиент — это получатель денежных средств. + +Механизм безопасных сделок используется для осуществления расчётов, при которых средства депонента временно холдируются и переходят к реципиенту только после выполнения условия сделки. При этом Банк ведет учёт (биллинг) денежных средств каждого бенефициара. + +Для работы с безопасными сделками предварительно необходимо: + +1. [Зарегистрировать контрагентов, участвующих в сделке, и их платёжные реквизиты](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro). +2. [Идентифицировать денежные средства, поступившие на номинальный счёт](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/intro/intro). + +> **Важно** +> В рамках этапа сделки выполнять платежи от бенефициара самому себе нельзя. Совершить такой перевод можно напрямую без создания сделки, используя метод [«Создание запроса на выплату с номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff). + +--- + +### Механизм работы сделок + +1. **Зарегистрируйте сделку** + Создайте черновик сделки для дальнейшего её наполнения этапами и участниками с помощью метода [«Регистрация сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal). + +2. **Создайте этапы сделки** + Используйте метод [«Выполнение действия по этапам сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + _Внимание!_ Каждая сделка должна содержать не менее одного этапа. + +3. **Добавьте депонента в этапы сделки** + Добавьте информацию о бенефициаре (плательщике) этапа с помощью метода [«Выполнение действия по участникам этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors). + _Внимание!_ В одном этапе сделки может быть указан только один депонент (плательщик). + +4. **Добавьте реципиентов в этапы сделки** + Добавьте информацию о получателях денежных средств с помощью метода [«Выполнение действия по участникам этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors). Реципиентами могут быть бенефициары или универсальные реципиенты. + _Внимание!_ В одном этапе сделки может быть несколько реципиентов. + +5. **Проверьте возможность выплат по сформированной сделке** + Проверьте правильность наполнения с помощью метода [«Проверка возможности осуществления выплат по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-is-valid/v1/deal-is-valid). Для перехода к следующему шагу необходимо получить в ответе `isValid = true`. + +6. **Подтвердите сделку** + Подтвердите создание с помощью метода [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). Статус изменится с `DRAFT` на `ACTIVE`. + _Внимание!_ При подтверждении сделки денежные средства депонентов холдируются. + +7. **Завершите этапы сделки** + Для проведения расчётов инициируйте завершение этапа через метод [«Выполнение действия по этапам сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + Для контроля используйте метод [«Получение статуса запроса на завершение этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status). При завершении этапа осуществляются выплаты. + +8. **Завершите сделку** + Используйте метод [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). Статус изменится с `ACTIVE` на `COMPLETED`. + +--- + +### Отмена сделки + +Для отмены используйте метод [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). + +> **Важно** +> Отменить сделку можно только при условии, что ни один из её этапов не был завершён. При отмене ранее захолдированные средства депонентов будут расхолдированы. + +--- + +### Информация о сделках и выплатах по ним + +**По сделкам:** + +- [Получение информации о сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal/v1/get-deal) +- [Получение списка сделок](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deals/v1/get-deals) + +**По этапам:** + +- [Получение информации об этапе сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-step/v1/get-step) +- [Получение списка этапов сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-steps/v1/get-steps) + +**По участникам:** + +- [Получить информацию об участниках этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-contractors/v1/get-contractors) + +**По переводам (платежам):** + +- [Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) + +--- + +**Навигация:** + +- Назад: [Получение статуса запроса на возврат неидентифицированного пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-transaction-refund-request-status/v1/get-transaction-refund-request-status) +- Вперед: [Регистрация сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/step-contractors.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/step-contractors.md new file mode 100644 index 0000000..55bd166 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Безопасные_сделки/step-contractors.md @@ -0,0 +1,137 @@ +# Выполнение действия по участникам этапа сделки + +**Метка:** `H2H` + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :----------------------------------------------------------------------- | +| **Песочница** | `PATCH https://sandbox.alfabank.ru/api/na/jp/v1/deals/steps/contractors` | +| **Пром** | `PATCH https://baas.alfabank.ru/api/na/jp/v1/deals/steps/contractors` | + +**Scope:** `deals` + +## Описание + +> **Внимание** +> Действия с участниками сделки возможны только для сделки в статусе `DRAFT`. + +Метод позволяет добавить, изменить или удалить участника сделки. + +### Добавление участника сделки + +Каждый этап сделки должен содержать участников. При добавлении необходимо учитывать: + +- В рамках одного этапа может быть добавлен только один депонент, реципиентов может быть несколько. +- В качестве депонента может выступать только бенефициар, в качестве реципиента – бенефициар или универсальный реципиент. +- При добавлении универсального реципиента необходимо передавать его идентификатор `universalRecipientId` в параметр `beneficiaryId`. +- Если не указан идентификатор платёжного реквизита `requisiteId`, система будет использовать [ранее зарегистрированный платёжный реквизит](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites), который считается основным (`isMain = true`). + +### Изменение участника сделки + +- **Для депонента:** можно изменить сумму депонированных средств. +- **Для реципиента:** можно изменить суммы, назначение платежа, признак вывода денег на виртуальный счёт и идентификатор платёжных реквизитов. + +### Удаление участника сделки + +Позволяет удалить депонента или реципиента из этапа сделки. + +--- + +## Параметры запроса + +### Headers + +| Атрибут | Тип | Описание | +| :---------------- | :------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` (required) | application/json | +| **Content-Type** | `string` (required) | application/json | + +### Body + +| Атрибут | Тип | Описание | +| :----------------------- | :---------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | +| **action** | `string` (required) | Тип действия: `ADD_DEPONENT`, `ADD_RECIPIENT`, `DELETE_DEPONENT`, `DELETE_RECIPIENT`, `UPDATE_DEPONENT`, `UPDATE_RECIPIENT` | +| **dealId** | `string` (required) | Идентификатор сделки | +| **stepId** | `string` (required) | Идентификатор этапа сделки | +| **beneficiaryId** | `string` (required) | Идентификатор бенефициара или универсального реципиента | +| **amount** | `string` (optional) | Сумма депонирования в рублях. Доступно только для депонента | +| **purpose** | `string` (optional) | Назначение платежа реципиента. Доступно только для реципиента | +| **amounts** | `array of objects` (optional) | Суммы реципиента. Доступно только для реципиента (см. ниже) | +| **keepOnNominalAccount** | `boolean` (optional) | Признак вывода на вирт. счёт: `true` — оставить на ном. счёте; `false` — вывести на реквизиты | +| **requisiteId** | `string` (optional) | Идентификатор платёжного реквизита контрагента | +| **digestSignatures** | `array of objects` (required) | Электронная подпись УЛ Клиента (см. ниже) | + +#### Объект `amounts` (внутри Body) + +| Атрибут | Тип | Описание | +| :------------- | :------------------ | :------------------------------------------------- | +| **walletType** | `string` (optional) | Тип кошелька: `MAIN` (основной), `TAX` (налоговый) | +| **amount** | `string` (optional) | Сумма в рублях | + +#### Объект `digestSignatures` (внутри Body) + +| Атрибут | Тип | Описание | +| :---------------- | :------------------ | :------------------------------------ | +| **base64Encoded** | `string` (required) | Значение подписи в Base64 | +| **signatureType** | `string` (required) | Тип подписи: `rsa` (RSA), `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/steps/contractors' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "action": "ADD_DEPONENT", + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "10.00", + "purpose": "Назначение платежа", + "amounts": [ + { + "walletType": "MAIN", + "amount": "10.00" + } + ], + "keepOnNominalAccount": true, + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +| Код | Статус | Описание | +| :------ | :-------------------- | :-------------------------------------------- | +| **204** | No Content | Успешное выполнение. Тело ответа отсутствует. | +| **400** | Bad Request | Неверные входные параметры. | +| **401** | Unauthorized | Токен просрочен или недействителен. | +| **403** | Forbidden | Недостаточно прав (insufficient_scope). | +| **404** | Not Found | Эндпоинт не найден. | +| **429** | Too Many Requests | Слишком много запросов. | +| **500** | Internal Server Error | Внутренняя ошибка сервиса. | +| **503** | Service Unavailable | Сервис временно недоступен. | + +### Структура ошибки (400, 401, 403, 404, 500) + +| Атрибут | Тип | Описание | +| :-------------------- | :------- | :------------------------------------------------------------------------------ | +| **error** | `string` | Код ошибки (например, `invalid_request`, `invalid_token`, `insufficient_scope`) | +| **error_description** | `string` | Подробное описание ошибки | + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff-request-status.md new file mode 100644 index 0000000..43cecab --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff-request-status.md @@ -0,0 +1,87 @@ +# Получение статуса запроса на выплату с номинального счёта + +**Тип интеграции:** H2H +**Scope:** `beneficiary-payments` + +## Описание +Метод позволяет получить статус запроса на выплату с номинального счёта по идентификатору `payoffId`. + +--- + +## Эндпоинты + +| Окружение | Метод | URL | +| :--- | :--- | :--- | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/status` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/status` | + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | `string` | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | required | `application/json` | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **payoffId** | `string` | required | Идентификатор запроса, полученный с помощью метода [«Создание запроса на выплату с номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff) | + +### Пример запроса (cURL) +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/status' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) +**Пример тела ответа:** +```json +{ + "payoffId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +**Описание полей BODY:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **payoffId** | `string` | required | Идентификатор запроса | +| **status** | `string` | required | Статус запроса (см. ниже) | +| **description** | `string` | optional | Описание причины, по которой запрос завершился неудачей. Возвращается, если статус равен `FAILED` | + +#### Возможные значения поля `status`: +* `PENDING` — запрос в процессе обработки; +* `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения отправки запроса-дубля на обработку; +* `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа; +* `FAILED` — обработка запроса завершилась ошибкой; +* `FAILED_DUPLICATE` — обработка запроса-дубля отклонена; +* `COMPLETE` — обработка запроса завершилась успешно. + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` / Примечание | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (scope) на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа. Превышен лимит запросов | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа. Сервис временно недоступен | + +--- + +## Дополнительные ссылки +* [Предыдущий шаг: Создание запроса на выплату](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff) +* [Следующий шаг: Подтверждение или отклонение запроса-дубля](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff-accept/v1/payoff-accept) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff.md new file mode 100644 index 0000000..07315ab --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-payoff.md @@ -0,0 +1,125 @@ +# Получение информации о платеже + +**Контекст:** Номинальные счета / Выплаты +**Тип интеграции:** H2H +**Scope:** `beneficiary-payments` + +## Эндпоинты + +| Окружение | Метод | URL | +| :------------ | :---- | :------------------------------------------------------------ | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}` | + +## Описание + +Метод позволяет получить информацию о платеже по его идентификатору `payoffId`. + +--- + +## Параметры запроса + +### Headers + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### Path + +| Атрибут | Тип | Обязательность | Описание | +| :----------- | :----- | :------------- | :-------------------- | +| **payoffId** | string | required | Идентификатор платежа | + +### Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +#### Тело ответа (JSON) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------- | +| **dealId** | string | optional | Идентификатор сделки | +| **stepId** | string | optional | Идентификатор этапа | +| **paymentType** | string | optional | Тип платежа: `REGULAR` (обычный), `DEAL` (выплата внутри сделки), `TAX` (налоговый) | +| **requisiteType** | string | optional | Тип реквизита: `ACCOUNT` (счёт), `CARD` (токен карты), `PHONE` (номер телефона) | +| **payer** | object | optional | Информация о плательщике (см. ниже) | +| **recipient** | object | optional | Информация о получателе (см. ниже) | +| **amount** | string | optional | Сумма в рублях | +| **purpose** | string | optional | Назначение платежа | +| **status** | string | optional | Статус: `IN_PROGRESS` (в обработке), `FAILED` (ошибка), `READY` (успешно завершён) | + +#### Объект `payer` (Плательщик) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :----------------------- | +| **accountNumber** | string | required | Номер счёта | +| **name** | string | required | Наименование организации | +| **inn** | string | required | ИНН | +| **kpp** | string | required | КПП | + +#### Объект `recipient` (Получатель) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :------------------------ | +| **beneficiaryId** | string | optional | Идентификатор бенефициара | +| **accountNumber** | string | optional | Номер счёта | +| **bik** | string | optional | БИК банка | +| **name** | string | optional | ФИО реципиента | +| **inn** | string | optional | ИНН | + +### Пример успешного ответа + +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "stepId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "paymentType": "REGULAR", + "requisiteType": "ACCOUNT", + "payer": { + "accountNumber": "40817810306050000000", + "name": "Акционерное общество «Ромашка»", + "inn": "1122334455", + "kpp": "123456789" + }, + "recipient": { + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566" + }, + "amount": "10.00", + "purpose": "Назначение платежа", + "status": "IN_PROGRESS" +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :------ | :-------------------- | :--------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (проверьте scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа (превышен лимит запросов) | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа (сервис временно недоступен) | + +--- + +_Документация Alfa API_ diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-tax-refund-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-tax-refund-request-status.md new file mode 100644 index 0000000..e951e2d --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/get-tax-refund-request-status.md @@ -0,0 +1,96 @@ +# Получение статуса запроса на возврат налоговых денежных средств + +**Тип интеграции:** H2H +**Продукт:** Номинальные счета +**Scope:** `beneficiary-payments` + +## Эндпоинты + +| Среда | Метод | URL | +| :------------ | :---- | :------------------------------------------------------------------------- | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/status` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/status` | + +--- + +## Описание + +Метод позволяет получить статус запроса на возврат бенефициару его денежных средств с налогового кошелька по идентификатору `taxRefundId`. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :-------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **taxRefundId** | string | required | Идентификатор запроса, полученный с помощью метода [«Создание запроса на возврат денежных средств с налогового виртуального кошелька»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund/v1/tax-refund) | + +### Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/status' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Пример тела ответа:** + +```json +{ + "taxRefundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "FAILED", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +**Описание полей BODY:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **taxRefundId** | string | required | Идентификатор запроса | +| **status** | string | required | Статус запроса (см. ниже) | +| **description** | string | optional | Описание причины неудачи. Возвращается только при статусе `FAILED` | + +#### Возможные значения статуса (`status`): + +- `PENDING` — запрос в процессе обработки; +- `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения отправки запроса-дубля на обработку; +- `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа; +- `FAILED` — обработка запроса завершилась ошибкой; +- `FAILED_DUPLICATE` — обработка запроса-дубля отклонена; +- `COMPLETE` — обработка запроса завершилась успешно. + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :-------------------- | :------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (проверьте настройки scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +## Навигация + +- **Предыдущий метод:** [Создание запроса на возврат налоговых денежных средств](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund/v1/tax-refund) +- **Следующий метод:** [Подтверждение или отклонение запроса-дубля на возврат налоговых денежных средств](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund-accept/v1/tax-refund-accept) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/intro.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/intro.md new file mode 100644 index 0000000..c5db172 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/intro.md @@ -0,0 +1,65 @@ +# Как это работает + +_Номинальные счета / Выплаты / Как это работает_ + +Для осуществления выплат с номинального счёта предварительно необходимо [зарегистрировать контрагента](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro), участвующего в выплате. + +## Общий механизм выплат с номинального счёта + +1. **Создайте запрос на выплату** + Метод [«Создание запроса на выплату с номинального счёта»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff) + +2. **Получите статус запроса на выплату** + Метод [«Получение статуса запроса на выплату с номинального счёта»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff-request-status/v1/get-payoff-request-status) + +3. **Подтвердите или отклоните обработку запроса-дубля на выплату** + В случае, если статус запроса на выплату уже был создан ранее, он примет статус `MANUAL_ACCEPTANCE` и его нужно будет подтвердить или отклонить. + Метод [«Подтвердить или отклонить запрос-дубль на выплату»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff-accept/v1/payoff-accept) + +4. **Получите информацию о платеже по его идентификатору** + Метод [«Получение информации о платеже»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff/v1/get-payoff) + +--- + +Выплаты с номинального счёта делятся на два типа: + +- выплаты без биллинга на стороне Банка; +- выплаты с биллингом на стороне Банка. + +## Выплаты без биллинга на стороне Банка + +Данный тип выплаты позволяет произвести выплату с номинального счёта в пользу зарегистрированного контрагента без создания сделки. + +Необходимо учитывать: + +- На номинальном счёте должен быть положительный баланс. +- Если выплата производится в пользу универсального реципиента, то для него предварительно необходимо зарегистрировать платёжные реквизиты с помощью метода [«Добавление платёжных реквизитов универсального реципиента»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-requisites/v1/add-requisites). + +В качестве платёжных реквизитов получателя могут быть указаны: + +- реквизиты счёта; +- номер телефона (СБП); +- зашифрованный номер карты (как зашифровать номер карты, описано [здесь](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken)); +- идентификатор платёжных реквизитов контрагента. + +## Выплаты с биллингом на стороне Банка + +> **Важно** +> +> У бенефициара должен быть положительный баланс на налоговом виртуальном счёте. + +- **Вывод собственных средств бенефициара с номинального счёта.** Позволяет вывести с номинального счёта денежные средства бенефициара без создания сделки. +- **Выплата с целью уплаты налога на профессиональный доход за исполнителя.** Позволяет аккумулировать денежные средства на виртуальном налоговом счёте исполнителя и перевести денежные средства бенефициара, задепонированные с целью уплаты налога на профессиональный доход за исполнителя, на счёт в управление казначейства. +- **Возврат денежных средств с налогового виртуального кошелька.** Позволяет вернуть денежные средства бенефициара, задепонированные с целью уплаты налога на профессиональный доход за исполнителя, если оплата налога не потребовалась. + +### Механизм возврата денежных средств с налогового виртуального кошелька + +1. **Создайте запрос на возврат денежных средств с налогового виртуального кошелька** + Метод [«Создание запроса на возврат денежных средств с налогового виртуального кошелька»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund/v1/tax-refund) + +2. **Получите статус запроса на возврат налоговых денежных средств** + Метод [«Получение статуса запроса на возврат налоговых денежных средств»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) + +3. **Подтвердите или отклоните обработку запроса-дубля на возврат денежных средств с налогового виртуального кошелька** + В случае, если статус запроса на выплату уже был создан ранее, он примет статус `MANUAL_ACCEPTANCE` и его нужно будет подтвердить или отклонить. + Метод [«Подтверждение или отклонение запроса-дубля на возврат денежных средств с налогового виртуального кошелька»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund-accept/v1/tax-refund-accept) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff-accept.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff-accept.md new file mode 100644 index 0000000..8317f80 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff-accept.md @@ -0,0 +1,87 @@ +Ниже представлен очищенный и структурированный анализ документа в формате Markdown. + +--- + +# Подтверждение или отклонение запроса-дубля на выплату + +**Тип интеграции:** H2H +**Продукт:** Номинальные счета / Выплаты +**Метод:** `PATCH` + +## Эндпоинты + +| Среда | URL | +| :--- | :--- | +| **Песочница** | `https://sandbox.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/accept` | +| **Пром** | `https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/accept` | + +## Scope +`beneficiary-payments` + +## Описание +Метод позволяет подтвердить или отклонить запрос на создание выплаты, находящийся в статусе `MANUAL_ACCEPTANCE`, по идентификатору `payoffId`. Это необходимо для обработки ситуаций, когда система зафиксировала потенциальный дубль запроса. + +--- + +## Параметры запроса + +### Headers (Заголовки) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | `Bearer {access_token}`, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### Path (Путь) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **payoffId** | string | Да | Идентификатор запроса, полученный методом [«Создание запроса на выплату с номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff) | + +### Body (Тело запроса) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **accept** | boolean | Да | Флаг обработки запроса-дубля:
• `true` – продолжить обработку;
• `false` – завершить (отклонить) обработку. | + +### Пример запроса (cURL) +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/accept' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accept": true +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **result** | boolean | Да | Статус обработки:
• `true` – обработка продолжена;
• `false` – обработка завершена. | + +**Пример JSON:** +```json +{ + "result": true +} +``` + +### Ошибки +| Код | Описание (error) | Описание (error_description) | +| :--- | :--- | :--- | +| **400** | `invalid_request` | Неверные входные параметры запроса. | +| **401** | `invalid_token` | Токен просрочен, отозван или имеет неверный формат. | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (недостаточный scope). | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен. | +| **429** | — | Too Many Requests (слишком много запросов). Тело ответа отсутствует. | +| **500** | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | — | Service Unavailable (сервис недоступен). Тело ответа отсутствует. | + +--- + +## Навигация +* **Назад:** [Получение статуса запроса на выплату с номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff-request-status/v1/get-payoff-request-status) +* **Вперед:** [Получение информации о платеже](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff/v1/get-payoff) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff.md new file mode 100644 index 0000000..b6f1849 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/payoff.md @@ -0,0 +1,157 @@ +Вот очищенная и структурированная версия документа в формате Markdown. + +--- + +# Создание запроса на выплату с номинального счёта + +**Тип интеграции:** H2H +**Scope:** `beneficiary-payments` + +## Эндпоинты + +* **Песочница:** `POST https://sandbox.alfabank.ru/api/na/jp/v1/payoffs` +* **Пром:** `POST https://baas.alfabank.ru/api/na/jp/v1/payoffs` + +## Описание +Метод позволяет вывести собственные средства бенефициара с номинального счёта по заранее зарегистрированным платёжным реквизитам (с биллингом) или осуществить выплату зарегистрированным контрагентам (без биллинга). + +> [!IMPORTANT] +> **Важно** +> Если идентичный запрос на выплату уже был создан ранее, то текущий запрос примет статус `MANUAL_ACCEPTANCE`. Его нужно будет подтвердить или отклонить с помощью метода [«Подтверждение или отклонение запроса-дубля на выплату»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff-accept/v1/payoff-accept). + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### BODY +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **type** | string | Да | Тип платежа: `REGULAR` (обычный), `TAX` (налоговый) | +| **accountNumber** | string | Да | Номер номинального счёта | +| **deponent** | string | Нет | Идентификатор бенефициара-плательщика | +| **recipient** | object | Да | **Получатель** (см. ниже) | +| **payoutRequisite** | object | Да | **Реквизиты обычного платежа** (см. ниже) | +| **requisites** | object | Нет | **Реквизиты для налогового платежа** (см. ниже) | +| **amount** | string | Да | Сумма в рублях | +| **purpose** | string | Да | Назначение платежа | +| **tax** | object | Нет | **Параметры для налогового платежа** (см. ниже) | +| **digestSignatures** | array | Да | **Электронная подпись УЛ клиента** (см. ниже) | + +#### Вложенный объект: recipient (Получатель) +* **type** (string, обязат.): Тип получателя. Значения: `BENEFICIARY` (контрагент), `SIMPLE_PAYEE` (простой получатель). +* **name** (string, опц.): Наименование (ФИО для ФЛ, название для ЮЛ/ИП). Обязательно для `SIMPLE_PAYEE`. +* **inn** (string, опц.): ИНН (12 цифр для ФЛ/ИП, 10 для ЮЛ). Обязательно для `SIMPLE_PAYEE`. +* **kpp** (string, опц.): КПП получателя. +* **beneficiaryId** (string, опц.): Идентификатор контрагента. Обязательно для `BENEFICIARY`. + +#### Вложенный объект: payoutRequisite (Реквизиты выплаты) +* **type** (string, обязат.): Тип реквизита: `ACCOUNT`, `CARD`, `PHONE`, `BENEFICIARY_REQUISITE`. +* **requisiteId** (string, опц.): ID реквизитов контрагента. Обязательно для `BENEFICIARY_REQUISITE`. +* **pan** (string, опц.): Токен номера карты. Обязательно для `CARD`. [Инструкция по токенизации](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken). +* **phoneNumber** (string, опц.): Номер телефона. Обязательно для `PHONE`. +* **bankId** (string, опц.): ID банка получателя. Обязательно для `PHONE`. +* **accountNumber** (string, опц.): Номер счёта. Обязательно для `ACCOUNT`. +* **bik** (string, опц.): БИК банка. Обязательно для `ACCOUNT`. + +#### Вложенный объект: tax (Налоговые параметры) +* **uin** (string, обязат.): УИН (поле 22). +* **payerStatus** (string, обязат.): Статус составителя (поле 101). Примеры: `01`, `02`, `08`, `13` и др. +* **kbk** (string, обязат.): КБК (поле 104). +* **oktmo** (string, обязат.): ОКТМО (поле 105). +* **reason** (string, обязат.): Основание платежа (поле 106). Примеры: `ТП`, `ЗД`, `0`. +* **period** (string, обязат.): Налоговый период (поле 107). Формат ДД.ММ.ГГГГ или `0`. +* **docNumber** (string, обязат.): Номер документа (поле 108). +* **docDate** (string, обязат.): Дата документа (поле 109). +* **paymentKind** (string, опц.): Код типа платежа (поле 110). `ПЕ`, `ПЦ` или `0`. + +#### Вложенный объект: digestSignatures (Подписи) +* **base64Encoded** (string, обязат.): Значение подписи в Base64. +* **signatureType** (string, обязат.): Тип подписи: `rsa` или `kep`. + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/payoffs' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "type": "REGULAR", + "accountNumber": "40817810306050000000", + "deponent": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "recipient": { + "type": "BENEFICIARY", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "payoutRequisite": { + "type": "ACCOUNT", + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593" + }, + "amount": "10.00", + "purpose": "Назначение платежа", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) +```json +{ + "payoffId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +**Описание полей ответа:** +* **payoffId** (string): Уникальный идентификатор платежа. +* **status** (string): Статус запроса. Возможные значения: + * `PENDING` — в процессе обработки. + * `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения (для дублей). + * `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа. + * `FAILED` — ошибка обработки. + * `FAILED_DUPLICATE` — запрос-дубль отклонен. + * `COMPLETE` — успешно завершено. + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав доступа | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* [Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/intro/intro) +* [Получение статуса запроса на выплату](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff-request-status/v1/get-payoff-request-status) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund-accept.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund-accept.md new file mode 100644 index 0000000..7d70d45 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund-accept.md @@ -0,0 +1,94 @@ +# Подтверждение или отклонение запроса-дубля на возврат налоговых денежных средств + +Данный метод API предназначен для управления запросами на возврат налоговых средств, которые получили статус `MANUAL_ACCEPTANCE` (требуют ручного подтверждения из-за обнаружения дубликата). + +## Общая информация + +- **Тип документа:** H2H +- **Метод:** `PATCH` +- **Scope:** `beneficiary-payments` + +## Эндпоинты + +| Среда | URL | +| :------------ | :------------------------------------------------------------------------- | +| **Песочница** | `https://sandbox.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/accept` | +| **Пром** | `https://baas.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/accept` | + +## Описание + +Метод позволяет подтвердить или отклонить запрос на возврат налоговых денежных средств, находящийся в статусе `MANUAL_ACCEPTANCE`, используя уникальный идентификатор `taxRefundId`. + +--- + +## Параметры запроса + +### Headers (Заголовки) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### PATH (Путь) + +| Атрибут | Тип | Обязательность | Описание | +| :-------------- | :----- | :------------- | :------------------------------- | +| **taxRefundId** | string | required | Идентификатор запроса на возврат | + +### QUERY (Параметры строки) + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :------ | :------------- | :-------------------------------------------------------------------------------------------------------- | +| **accept** | boolean | required | Флаг обработки дубля:
• `true` – продолжить обработку;
• `false` – завершить (отклонить) обработку. | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH \ +'https://baas.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/accept?accept={accept}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Тело ответа (JSON):** + +```json +{ + "result": true +} +``` + +**Описание полей:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **result** | boolean | required | Статус обработки: `true` — продолжена, `false` — завершена. | + +--- + +## Коды ошибок + +| Код | Статус | Ошибка (`error`) | Описание | +| :------ | :------------------ | :------------------- | :----------------------------------------------------- | +| **400** | Bad Request | `invalid_request` | Неверные входные параметры запроса. | +| **401** | Unauthorized | `invalid_token` | Токен просрочен, отозван или имеет неверный формат. | +| **403** | Forbidden | `insufficient_scope` | Нет прав на использование сервиса (не настроен scope). | +| **404** | Not Found | `unknown_endpoint` | Эндпоинт не найден или неактивен. | +| **429** | Too Many Requests | — | Слишком много запросов (нет тела ответа). | +| **500** | Internal Error | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | Service Unavailable | — | Сервис временно недоступен (нет тела ответа). | + +--- + +## Навигация + +- **Предыдущий шаг:** [Получение статуса запроса на возврат налоговых денежных средств](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) +- **Раздел:** Номинальные счета / Выплаты diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund.md new file mode 100644 index 0000000..da1b258 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Выплаты/tax-refund.md @@ -0,0 +1,121 @@ +# Создание запроса на возврат налоговых денежных средств + +**Продукт:** Alfa API / Номинальные счета / Выплаты +**Тип интеграции:** H2H +**Scope:** `beneficiary-payments` + +## Эндпоинты + +| Окружение | Метод | URL | +| :------------ | :----- | :---------------------------------------------------- | +| **Песочница** | `POST` | `https://sandbox.alfabank.ru/api/na/jp/v1/tax-refund` | +| **Пром** | `POST` | `https://baas.alfabank.ru/api/na/jp/v1/tax-refund` | + +## Описание + +Метод позволяет создать запрос на возврат бенефициару его денежных средств с налогового кошелька, если оплата налога не потребовалась. + +- Если нужно вернуть налоговые средства на основной виртуальный счёт бенефициара без вывода с номинального счёта, передавайте `keepOnNominalAccount = true`. +- Если нужно вернуть налоговые средства бенефициару с выводом с номинального счёта, передавайте `keepOnNominalAccount = false`. + +> [!IMPORTANT] +> **Важно** +> Если идентичный запрос на возврат налоговых денежных средств уже был создан ранее, то текущий запрос примет статус `MANUAL_ACCEPTANCE`. Его нужно будет подтвердить или отклонить с помощью метода [«Подтверждение или отклонение запроса-дубля на возврат налоговых денежных средств»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund-accept/v1/tax-refund-accept). + +## Параметры запроса + +### Заголовки (Headers) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/json` | + +### Тело запроса (Body) + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------- | :------ | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **beneficiaryId** | string | required | Идентификатор бенефициара | +| **amount** | string | required | Сумма | +| **purpose** | string | required | Назначение платежа | +| **keepOnNominalAccount** | boolean | required | Признак вывода денег на основной виртуальный счёт.
• `true` — оставить в рамках номинального счёта;
• `false` — вывести по идентификатору платёжного реквизита бенефициара. | +| **requisiteId** | string | optional | Идентификатор платёжного реквизита бенефициара для вывода. Если не заполнено, используются основные реквизиты. | +| **digestSignatures** | array | required | Массив объектов электронной подписи УЛ клиента. | + +**Объект в digestSignatures:** + +- **base64Encoded** (string, required): Значение электронной подписи в Base64. +- **signatureType** (string, required): Тип подписи: `rsa` (RSA) или `kep` (КЭП). + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/tax-refund' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "10.00", + "purpose": "Назначение платежа", + "keepOnNominalAccount": false, + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) + +| Атрибут | Тип | Обязательность | Описание | +| :-------------- | :----- | :------------- | :--------------------------------------- | +| **taxRefundId** | string | required | Идентификатор возврата налоговых средств | +| **status** | string | required | Статус запроса (см. ниже) | + +**Возможные значения статуса:** + +- `PENDING` — запрос в процессе обработки; +- `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения запроса-дубля; +- `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа; +- `FAILED` — ошибка обработки; +- `FAILED_DUPLICATE` — запрос-дубль отклонен; +- `COMPLETE` — успешно завершено. + +**Пример ответа 202:** + +```json +{ + "taxRefundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :---------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен или просрочен | +| **403** | Forbidden | `insufficient_scope` — нет прав (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Связанные методы:** + +- [Получение информации о платеже](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff/v1/get-payoff) +- [Получение статуса запроса на возврат налоговых денежных средств](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-identify-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-identify-request-status.md new file mode 100644 index 0000000..cc9caf3 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-identify-request-status.md @@ -0,0 +1,96 @@ +# Получение статуса запроса на идентификацию пополнения номинального счёта + +**Тип интеграции:** H2H + +--- + +### Эндпоинты + +**Песочница** +`GET https://sandbox.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify/{identifyId}` + +**Пром** +`GET https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify/{identifyId}` + +--- + +### Scope + +`beneficiary-payments` + +--- + +### Описание + +Метод позволяет получить статус запроса на идентификацию операции пополнения по `identifyId`. + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Описание | +| :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** _string, required_ | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** _string, required_ | application/json | + +#### PATH + +| Атрибут | Описание | +| :-------------------------------- | :--------------------------------------------------------- | +| **id** _string, required_ | Идентификатор операции пополнения | +| **identifyId** _string, required_ | Идентификатор запроса на идентификацию операции пополнения | + +--- + +### Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify/{identifyId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +### Параметры ответа + +#### 200 (OK) — BODY + +| Атрибут | Описание | +| :--------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **identifyId** _string, required_ | Идентификатор запроса на идентификацию операции пополнения | +| **status** _string, required_ | Статус запроса. Возможные значения: `PENDING` - в процессе обработки;`VALIDATED` - провалидирован;`FAILED` - возникла ошибка;`COMPLETE` - обработан успешно | +| **description** _string, optional_ | Описание причины, по которой запрос завершился неудачей. Возвращается, если статус запроса равен `FAILED` | + +#### Пример ответа 200 (OK) + +```json +{ + "identifyId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +--- + +### Ошибки + +| Код | Описание | +| :-------------------------- | :------------------------------------------------------------------- | +| **400 Bad Request** | `invalid_request` — неверные входные параметры запроса | +| **401 Unauthorized** | `invalid_token` — предоставленный токен просрочен или недействителен | +| **403 Forbidden** | `insufficient_scope` — недостаточно прав (не настроен scope) | +| **404 Not Found** | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429 Too Many Requests** | Превышен лимит запросов (тело ответа отсутствует) | +| **500 Internal Error** | `internal_error` — внутренняя ошибка сервиса | +| **503 Service Unavailable** | Сервис временно недоступен (тело ответа отсутствует) | + +--- + +**Навигация:** + +- [Предыдущий метод: Создание запроса на идентификацию](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/identify/v1/identify) +- [Следующий метод: Создание запроса на возврат](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/transaction-refund/v1/transaction-refund) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-transaction-refund-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-transaction-refund-request-status.md new file mode 100644 index 0000000..f10c359 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-transaction-refund-request-status.md @@ -0,0 +1,78 @@ +# Получение статуса запроса на возврат неидентифицированного пополнения + +**Тип интеграции:** H2H + +## Эндпоинты + +**Песочница** +`GET https://sandbox.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}` + +**Пром** +`GET https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}` + +## Scope +`beneficiary-payments` + +## Описание +Метод позволяет получить статус запроса на возврат неидентифицированного пополнения по `refundId`. + +## Параметры запроса + +### HEADERS +| Атрибут | Описание | +| :--- | :--- | +| **Authorization**
`string`, required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
`string`, required | application/json | + +### PATH +| Атрибут | Описание | +| :--- | :--- | +| **id**
`string`, required | Идентификатор операции пополнения, по которой необходимо вернуть денежные средства | +| **refundId**
`string`, required | Идентификатор запроса на возврат неидентифицированного пополнения, полученный с помощью метода [«Создание запроса на возврат неидентифицированного пополнения»](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/transaction-refund/v1/transaction-refund) | + +### Пример запроса (cURL) +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 (OK) +**BODY** +| Атрибут | Описание | +| :--- | :--- | +| **refundId**
`string`, required | Уникальный идентификатор запроса на возврат неидентифицированного пополнения | +| **status**
`string`, required | Статус запроса. Принимает возможные значения:
• `PENDING` - запрос в процессе обработки;
• `FAILED` - обработка запроса завершилась ошибкой;
• `COMPLETE` - обработка запроса завершилась успешно | +| **description**
`string`, optional | Описание причины, по которой запрос завершился ошибкой.
**Примечание:** поле доступно только при статусе запроса `FAILED` | + +#### Пример ответа 200 (OK) +```json +{ + "refundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "FAILED", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (отсутствует нужный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* Предыдущий метод: [Создание запроса на возврат неидентифицированного пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/transaction-refund/v1/transaction-refund) +* Следующий раздел: [Безопасные сделки: Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-unidentified-transactions.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-unidentified-transactions.md new file mode 100644 index 0000000..555517c --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/get-unidentified-transactions.md @@ -0,0 +1,123 @@ +# Получение списка неидентифицированных пополнений номинального счёта + +**Тип интеграции:** H2H + +Метод позволяет получить информацию о транзакциях пополнения номинального счёта, которые не проходили процедуру идентификации. + +--- + +## Эндпоинты + +### Песочница +`GET https://sandbox.alfabank.ru/api/na/jp/v1/unidentified-transactions` + +### Пром +`GET https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions` + +--- + +## Scope +`beneficiary-payments` + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | + +### QUERY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **accountNumber** | string | required | Номер номинального счёта | +| **limit** | integer | optional | Количество объектов на одной странице | +| **offset** | integer | optional | Количество объектов в списке, которые необходимо пропустить | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions?accountNumber=40817810306050000000&limit=100&offset={offset}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Ответ 200 (OK) — BODY + +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **offset** | integer | required | Порядковый номер первого неидентифицированного пополнения в списке | +| **limit** | integer | required | Порядковый номер последнего неидентифицированного пополнения в списке | +| **totalCount** | integer | required | Всего неидентифицированных пополнений | +| **unidentifiedTransactions** | array of objects | optional | Список неидентифицированных пополнений | + +#### Объект unidentifiedTransactions: +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **id** | string | required | ID операции пополнения | +| **documentNumber** | string | optional | Номер платёжного поручения | +| **date** | string | optional | Дата и время пополнения по МСК | +| **amount** | string | required | Сумма пополнения в рублях | +| **purpose** | string | optional | Назначение платежа | +| **payer** | object | optional | Информация о плательщике | + +#### Объект payer: +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **inn** | string | optional | ИНН плательщика | +| **kpp** | string | optional | КПП плательщика | +| **accountNumber** | string | optional | Номер счёта плательщика | +| **name** | string | optional | Имя плательщика | +| **bankAccount** | string | optional | Номер счёта банка плательщика | +| **bankBik** | string | optional | БИК банка плательщика | +| **bankName** | string | optional | Наименования банка плательщика | + +### Пример ответа 200 + +```json +{ + "offset": 0, + "limit": 100, + "totalCount": 1, + "unidentifiedTransactions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "documentNumber": "Номер платёжного поручения", + "date": "2025-04-08T10:47:17.927Z", + "amount": "10.00", + "purpose": "Назначение платежа", + "payer": { + "inn": "221284672706", + "kpp": "641914992", + "accountNumber": "87149728127096890679", + "name": "Имя плательщика", + "bankAccount": "3932755239052037086628", + "bankBik": "108997635", + "bankName": "Наименования банка плательщика" + } + } + ] +} +``` + +--- + +## Ошибки + +| Код | Описание (error) | error_description / Комментарий | +| :--- | :--- | :--- | +| **400** | `invalid_request` | неверные входные параметры запроса | +| **401** | `invalid_token` | предоставленный токен просрочен, отозван или недействителен | +| **403** | `insufficient_scope` | у пользователя нет прав на использование сервиса (настройки scope) | +| **404** | `unknown_endpoint` | эндпоинт не найден или неактивен | +| **429** | — | Too Many Requests (Нет тела ответа) | +| **500** | `internal_error` | внутренняя ошибка сервиса | +| **503** | — | Service Unavailable (Нет тела ответа) | diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/how_it_works_intro.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/how_it_works_intro.md new file mode 100644 index 0000000..826983d --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/how_it_works_intro.md @@ -0,0 +1,23 @@ +# Как это работает + +**Теги:** `H2H` + +Депонент (бенефициар) может пополнить номинальный счёт удобным ему способом, после чего владелец номинального счёта должен идентифицировать поступившие денежные средства. + +Для этого владельцу счёта необходимо: + +1. **Получить информацию обо всех неидентифицированных пополнениях** + - Метод [«Получение списка неидентифицированных пополнений номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-unidentified-transactions/v1/get-unidentified-transactions) + +2. **Создать запрос на идентификацию денежных средств** + - Метод [«Создание запроса на идентификацию пополнения номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/identify/v1/identify) + +3. **Получить статус запроса на идентификацию денежных средств** + - Метод [«Получение статуса запроса на идентификацию пополнения номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-identify-request-status/v1/get-identify-request-status) + +--- + +### Навигация + +- ← [Изменение признаков платёжных реквизитов универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/change-requisites/v1/change-requisites) +- → [Получение списка неидентифицированных пополнений номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-unidentified-transactions/v1/get-unidentified-transactions) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/identify.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/identify.md new file mode 100644 index 0000000..1efcda2 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/identify.md @@ -0,0 +1,108 @@ +Вот очищенная и структурированная версия документации в формате Markdown: + +# Создание запроса на идентификацию пополнения номинального счёта + +**Тип интеграции:** H2H + +## Эндпоинты + +**Песочница:** +`POST https://sandbox.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify` + +**Пром:** +`POST https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify` + +--- + +## Scope +`beneficiary-payments` + +## Описание +Метод позволяет создать запрос на идентификацию одной из операций пополнения с помощью распределения суммы по бенефициарам. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | application/json | +| **Content-Type** | string | Да | application/json | + +### PATH +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **id** | string | Да | Идентификатор операции пополнения, которую необходимо распределить между бенефициарами | + +### BODY +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **transactionId** | string | Да | Идентификатор операции пополнения | +| **accountNumber** | string | Да | Номер номинального счёта | +| **amountDistribution** | array of objects | Да | Распределение денежных средств (список бенефициаров) | +| └─ **beneficiaryId** | string | Да | Идентификатор бенефициара | +| └─ **amount** | string | Да | Сумма пополнения в рублях | +| **digestSignatures** | array of objects | Да | Электронная подпись УЛ клиента | +| └─ **base64Encoded** | string | Да | Значение электронной подписи в Base64 | +| └─ **signatureType** | string | Да | Тип подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/identify' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "transactionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "accountNumber": "40817810306050000000", + "amountDistribution": [ + { + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "10.00" + } + ], + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 202 Accepted (Успешно принято) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **identifyId** | string | Идентификатор созданного запроса | +| **status** | string | Статус запроса: `PENDING` (в процессе), `VALIDATED` (провалидирован), `FAILED` (ошибка), `COMPLETE` (успешно) | + +**Пример ответа 202:** +```json +{ + "identifyId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +### Ошибки +* **400 Bad Request:** `invalid_request` — неверные входные параметры. +* **401 Unauthorized:** `invalid_token` — токен просрочен или недействителен. +* **403 Forbidden:** `insufficient_scope` — нет прав на использование сервиса. +* **404 Not Found:** `unknown_endpoint` — эндпоинт не найден. +* **429 Too Many Requests:** Превышен лимит запросов (тело ответа отсутствует). +* **500 Internal Server Error:** `internal_error` — внутренняя ошибка сервиса. +* **503 Service Unavailable:** Сервис временно недоступен (тело ответа отсутствует). + +--- +**Навигация:** +* [Предыдущая: Получение списка неидентифицированных пополнений](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-unidentified-transactions/v1/get-unidentified-transactions) +* [Следующая: Получение статуса запроса на идентификацию](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-identify-request-status/v1/get-identify-request-status) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/transaction-refund.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/transaction-refund.md new file mode 100644 index 0000000..6490927 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Идентификация_пополнений/transaction-refund.md @@ -0,0 +1,112 @@ +# Создание запроса на возврат неидентифицированного пополнения + +**Тип интеграции:** H2H +**Продукт:** Номинальные счета + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds` | + +## Scope +`beneficiary-payments` + +## Описание +Метод позволяет создать запрос на возврат неидентифицированного пополнения. + +--- + +## Параметры запроса + +### Headers +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **id** | string | required | Идентификатор операции пополнения, по которой необходимо вернуть денежные средства | + +### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **accountNumber** | string | required | Номер номинального счета | +| **id** | string | required | Идентификатор операции пополнения, по которой необходимо вернуть денежные средства | +| **digestSignatures** | array of objects | required | Электронная подпись УЛ клиента (см. детали ниже) | + +#### Детали объекта digestSignatures +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **base64Encoded** | string | required | Значение электронной подписи, закодированное в Base64 | +| **certificateUuid** | string | optional | Идентификатор сертификата, использованного при создании электронной подписи | +| **signatureType** | string | required | Тип электронной подписи. Возможные значения: `rsa` (RSA), `kep` (КЭП) | +| **poaNumber** | string | optional | Номер машиночитаемой доверенности | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accountNumber": "40817810306050000000", + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "certificateUuid": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "signatureType": "rsa", + "poaNumber": "DOVER_CBR_7702235133_20211102_1" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 202 (Accepted) +Запрос успешно принят в обработку. + +**Пример тела ответа:** +```json +{ + "refundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +**Описание полей:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **refundId** | string | required | Уникальный идентификатор запроса на возврат неидентифицированного пополнения | +| **status** | string | required | Статус запроса: `PENDING` (в процессе), `FAILED` (ошибка), `COMPLETE` (успешно) | + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Превышено количество запросов (нет тела ответа) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Сервис недоступен (нет тела ответа) | + +--- + +**Следующие шаги:** +* [Получение статуса запроса на возврат неидентифицированного пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-transaction-refund-request-status/v1/get-transaction-refund-request-status) +* [Получение статуса запроса на идентификацию пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-identify-request-status/v1/get-identify-request-status) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/get-request-status.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/get-request-status.md new file mode 100644 index 0000000..c33a8f6 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/get-request-status.md @@ -0,0 +1,96 @@ +# Получение статуса запроса + +**Тип интеграции:** H2H +**Scope:** `beneficiaries` + +Метод позволяет получить статус запроса на регистрацию, изменение или проверку контрагента (бенефициара или универсального реципиента) по идентификатору соответствующего запроса. + +--- + +## Эндпоинты + +### Песочница + +`GET https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/requests/{requestId}/status` + +### Пром + +`GET https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/requests/{requestId}/status` + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :------------ | :----- | :------------- | :-------------------------------------------------------------------------------------------------------- | +| **requestId** | string | required | Идентификатор запроса, полученный при создании запроса на регистрацию, изменение или проверку контрагента | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/requests/{requestId}/status' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Пример тела ответа:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE", + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "universalRecipientId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2", + "resultData": "Данные субъекта не прошли проверку: N05 PBS0023\nСубъект не прошел скоринг и деактивирован в системе.\n" +} +``` + +**Описание полей BODY:** + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------- | :----- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **requestId** | string | required | Идентификатор запроса | +| **status** | string | required | Статус запроса. Возможные значения:
• `PENDING` – запрос в процессе обработки;
• `FAILED` – обработка запроса завершилась ошибкой;
• `COMPLETE` – обработка запроса завершилась успешно | +| **beneficiaryId** | string | optional | Идентификатор бенефициара. Возвращается при получении статуса запроса на регистрацию бенефициара | +| **universalRecipientId** | string | optional | Идентификатор универсального реципиента. Возвращается при получении статуса запроса на регистрацию универсального реципиента | +| **description** | string | optional | Описание причины, по которой запрос завершился неудачей. Возвращается, если статус запроса равен `FAILED` | +| **resultData** | string | optional | Результаты прохождения проверки. Возвращается при получении статуса запроса на проверку бенефициара | + +--- + +## Ошибки + +| Код | Описание | Ошибка (`error`) | Детали | +| :------ | :-------------------- | :------------------- | :--------------------------------------------------- | +| **400** | Bad Request | `invalid_request` | Неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` | Токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` | Нет прав на использование сервиса (настройки scope) | +| **404** | Not Found | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | Too Many Requests | — | Превышен лимит запросов (тело ответа отсутствует) | +| **500** | Internal Server Error | `internal_error` | Внутренняя ошибка сервиса | +| **503** | Service Unavailable | — | Сервис временно недоступен (тело ответа отсутствует) | + +--- + +**Навигация:** + +- [← Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro) +- [Создание запроса на регистрацию бенефициара →](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-beneficiary/v1/add-beneficiary) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/intro.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/intro.md new file mode 100644 index 0000000..b8cca14 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/intro.md @@ -0,0 +1,81 @@ +Вот преобразованный текст из HTML-файла в формат Markdown. Я сохранил структуру, иерархию заголовков, важные примечания и все ссылки. + +--- + +# Как это работает + +При проведении расчётов через номинальные счета необходимо обмениваться информацией о контрагентах: бенефициарах и универсальных реципиентах. Для этого необходимо предварительно зарегистрировать контрагентов и их платёжные реквизиты. + +## Регистрация контрагентов и платёжных реквизитов + +Перед проведением расчётов через номинальные счета пройдите следующие шаги: + +### 1. Зарегистрируйте контрагентов + +**Бенефициары** +До совершения расчётов с участием бенефициара необходимо предоставить в Банк сведения о бенефициаре и зарегистрировать его в системе. +Каждому бенефициару в рамках номинального счёта будет присвоен уникальный идентификатор — `beneficiaryId`. + +Для этого используются методы: +* [«Создание запроса на регистрацию бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-beneficiary/v1/add-beneficiary) +* [«Получение статуса запроса»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/get-request-status/v1/get-request-status) + +**Универсальные реципиенты** +При осуществлении переводов с номинального счёта, помимо бенефициаров, получателем денежных средств может быть универсальный реципиент. Для участия универсального реципиента в сделке его также необходимо зарегистрировать. +Каждому универсальному реципиенту в рамках номинального счёта будет присвоен уникальный идентификатор — `universalRecipientId`. + +Для этого используются методы: +* [«Создание запроса на регистрацию универсального реципиента»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-ur/v1/add-ur) +* [«Получение статуса запроса»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/get-request-status/v1/get-request-status) + +### 2. Зарегистрируйте платёжные реквизиты контрагентов + +После регистрации бенефициара или универсального реципиента необходимо указать платёжные реквизиты, на которые он будет получать денежные средства. + +Для этого используются методы: +* [«Добавление платёжных реквизитов бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites) +* [«Добавление платёжных реквизитов универсального реципиента»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-requisites/v1/add-requisites) + +--- + +## Изменение информации о бенефициаре + +Изменить данные о бенефициаре можно с помощью методов: +* [«Создание запроса на изменение информации о бенефициаре»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-beneficiary/v1/change-beneficiary) +* [«Получение статуса запроса»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/get-request-status/v1/get-request-status) + +В случае, если бенефициар больше не является участником расчётов и на его виртуальных счетах не осталось денежных средств, необходимо направить запрос на деактивацию бенефициара. Если в дальнейшем на номинальный счёт деактивированного бенефициара снова поступят денежные средства, его необходимо будет активировать. + +## Проверка актуальности данных бенефициара + +Проверить актуальность ранее зарегистрированных данных о бенефициаре можно с помощью методов: +* [«Создание запроса на проверку бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/beneficiary-scoring/v1/beneficiary-scoring) +* [«Получение статуса запроса»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/get-request-status/v1/get-request-status) + +## Изменение признаков платёжных реквизитов контрагентов + +Изменить признаки платёжных реквизитов контрагентов можно с помощью методов: +* [«Изменение признаков платёжных реквизитов бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-requisites/v1/change-requisites) +* [«Изменение признаков платёжных реквизитов универсального реципиента»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/change-requisites/v1/change-requisites) + +--- + +## Учёт денежных средств бенефициара + +> **Важно** +> Биллинг для универсальных реципиентов не проводится, поскольку они не являются бенефициарами и не могут иметь собственных средств на номинальном счёте. + +> **Внимание** +> Учёт денежных средств на виртуальных счетах бенефициаров будет вестись корректно только при условии, что владелец номинального счёта не использует другие каналы вывода средств (банк-клиент, бумажные поручения и др.). + +Для учёта денежных средств бенефициара — биллинга на стороне Банка — используются **виртуальные счета**. + +При регистрации бенефициара по умолчанию создается **основной виртуальный счёт**. На нём учитываются денежные средства, права на которые принадлежат бенефициару. В случае необходимости уплаты налога (при [добавлении бенефициара в качестве реципиента в этап сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors)) дополнительно создаётся **налоговый виртуальный счёт**. + +Виртуальный счёт состоит из доступных и захолдированных денежных средств: +* **Доступные денежные средства** не обременены обязательствами, их можно использовать при проведении расчётов или вывести с номинального счёта. +* **Захолдированные денежные средства** — деньги, которые уже участвуют в незавершенной сделке, их нельзя использовать для других целей или вывести. + +### Информация о балансе и операциях бенефициара +* Узнать балансы по виртуальным счетам можно с помощью метода [«Получение информации о балансе бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-balance/v1/get-balance). +* Получить список денежных операций бенефициара можно с помощью метода [«Получение списка денежных операций бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-transactions/v1/get-transactions). diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-beneficiary.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-beneficiary.md new file mode 100644 index 0000000..d6ab987 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-beneficiary.md @@ -0,0 +1,186 @@ +# Создание запроса на регистрацию бенефициара + +**H2H** + +### Эндпоинты + +| Среда | Метод и URL | +| :------------ | :------------------------------------------------------------ | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/beneficiaries` | + +### Scope + +`beneficiaries` + +### Описание + +Метод позволяет зарегистрировать бенефициара (контрагента с признаком `isBeneficiary = TRUE`) в системе. + +> **Важно** +> В зависимости от типа бенефициара необходимо по-разному заполнять поля запроса. + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------------ | :------ | :------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| **accountNumber** | string | required | Номер номинального счёта | +| **type** | string | required | Тип бенефициара. Возможные значения: `FL_RESIDENT`, `FL_NONRESIDENT`, `UL_RESIDENT`, `UL_NONRESIDENT`, `IP_RESIDENT`, `IP_NONRESIDENT` | +| **taxResidentUS** | boolean | required | Признак налогового резидента США | +| **foreignTaxResident** | boolean | required | Признак иностранного налогового резидента | +| **financialActivities** | boolean | optional | Признак осуществления финансовой деятельности. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **countryOfTaxResidence** | string | required | Страна налогового резидентства (ISO 3166-1 alpha-2) | +| **name** | string | optional | Наименование организации. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **registrationDate** | string | optional | Дата регистрации. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **inn** | string | optional | ИНН. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT`. Для ФЛ/ИП указывается в `personalInformation` | +| **kpp** | string | optional | КПП. Обязательно для `UL_RESIDENT` | +| **ogrn** | string | optional | ОГРН. Обязательно для `UL_RESIDENT` | +| **personalInformation** | object | optional | Персональные данные. Заполняется только для ФЛ и ИП | +| **phoneNumber** | string | optional | Телефон | +| **email** | string | optional | Адрес электронной почты | +| **addresses** | array | required | Список адресов бенефициара | +| **documents** | array | optional | Документы (подробнее ниже) | +| **digestSignatures** | array | required | Электронная подпись УЛ клиента | + +--- + +### Детальное описание объектов + +#### personalInformation (для ФЛ и ИП) + +| Атрибут | Тип | Описание | +| :-------------- | :----- | :------------------------------------------------ | +| **inn** | string | ИНН. Обязательно для резидентов и нерезидентов ИП | +| **firstName** | string | Имя | +| **middleName** | string | Отчество (optional) | +| **lastName** | string | Фамилия | +| **citizenship** | string | Гражданство: `RU`, `BY`, `AM`, `KZ`, `KG` | +| **birthDate** | string | Дата рождения | +| **birthPlace** | string | Место рождения | +| **snils** | string | СНИЛС. Обязательно для резидентов | + +#### addresses + +| Атрибут | Тип | Описание | +| :---------- | :----- | :------------------------------------------------------------------ | +| **type** | string | `REGISTRATION_ADDRESS`, `RESIDENCE_ADDRESS`, `LEGAL_ENTITY_ADDRESS` | +| **address** | string | Текстовый адрес | +| **country** | string | Код страны (ISO 3166-1 alpha-2) | + +#### documents + +_Для резидентов обязателен `PASSPORT`. Для граждан РБ — `FOREIGN_PASSPORT`. Для остальных нерезидентов — не менее 2 документов._ + +| Атрибут | Тип | Описание | +| :--------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------ | +| **type** | string | `PASSPORT`, `FOREIGN_PASSPORT`, `RESIDENCE_PERMIT`, `STATELESS_RESIDENCE_CERTIFICATE`, `TEMPORARY_RESIDENCE_PERMIT`, `MIGRATION_CARD` | +| **serial** | string | Серия (optional) | +| **number** | string | Номер | +| **issueDate** | string | Дата выдачи | +| **expireDate** | string | Дата истечения (optional) | +| **division** | string | Код подразделения (optional) | +| **organization** | string | Орган, выдавший документ | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data-raw '{ + "accountNumber": "40817810306050000000", + "type": "FL_RESIDENT", + "taxResidentUS": false, + "foreignTaxResident": false, + "financialActivities": false, + "countryOfTaxResidence": "RU", + "name": "Акционерное общество «Ромашка»", + "registrationDate": "2025-12-18", + "inn": "0123456789", + "kpp": "0123456789", + "ogrn": "0123456789101", + "personalInformation": { + "inn": "112233445566", + "firstName": "Иван", + "middleName": "Иванoвич", + "lastName": "Иванов", + "citizenship": "RU", + "birthDate": "2000-03-02", + "birthPlace": "Г. Иркутск", + "snils": "12345678910" + }, + "phoneNumber": "79130000011", + "email": "IvanovIvan@mail.ru", + "addresses": [ + { + "type": "REGISTRATION_ADDRESS", + "address": "ул. Максима Горького 55", + "country": "RU" + } + ], + "documents": [ + { + "type": "PASSPORT", + "serial": "6953", + "number": "987435", + "issueDate": "2022-03-02", + "expireDate": "2022-03-02", + "division": "123-321", + "organization": "ОВД Иркутской области по Г. Иркутску по Октябрьскому району" + } + ], + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +#### 202 Accepted + +Запрос принят в обработку. + +| Атрибут | Тип | Описание | +| :------------ | :----- | :---------------------------------------------------------------------- | +| **requestId** | string | Идентификатор запроса | +| **status** | string | Статус: `PENDING` (в процессе), `FAILED` (ошибка), `COMPLETE` (успешно) | + +**Пример ответа 202:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +#### Коды ошибок + +- **400 Bad Request**: `invalid_request` — неверные параметры. +- **401 Unauthorized**: `invalid_token` — токен недействителен. +- **403 Forbidden**: `insufficient_scope` — нет прав доступа (недостаточный scope). +- **404 Not Found**: `unknown_endpoint` — эндпоинт не найден. +- **429 Too Many Requests**: Превышен лимит запросов. +- **500 Internal Server Error**: `internal_error` — внутренняя ошибка сервера. +- **503 Service Unavailable**: Сервис временно недоступен. diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-requisites.md new file mode 100644 index 0000000..dcecf15 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/add-requisites.md @@ -0,0 +1,129 @@ +# Добавление платёжных реквизитов бенефициара + +tags: `H2H` + +## Эндпоинты + +| Среда | Метод и URL | +| :------------ | :--------------------------------------------------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites` | + +## Scope + +`beneficiaries` + +## Описание + +Метод позволяет добавить платёжные реквизиты бенефициара по `beneficiaryId`. + +> **Важно** +> Первые добавленные реквизиты автоматически назначаются основными для бенефициара. + +--- + +## Параметры запроса + +### Headers + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### Path + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :------------------------ | +| **beneficiaryId** | string | Да | Идентификатор бенефициара | + +### Body + +| Атрибут | Тип | Обяз. | Описание | +| :------------------- | :------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **beneficiaryId** | string | Нет | Идентификатор бенефициара | +| **type** | string | Да | Тип платёжного реквизита. Возможные значения:
• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | +| **pan** | string | Нет | Токен номера карты. Поле обязательно при типе `CARD`. [Как сформировать токен](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **phoneNumber** | string | Нет | Номер телефона. Поле обязательно при типе `PHONE` | +| **bankId** | string | Нет | Идентификатор банка контрагента-получателя. Поле обязательно при типе `PHONE` | +| **accountNumber** | string | Нет | Номер счёта. Поле обязательно при типе `ACCOUNT` | +| **bik** | string | Нет | БИК банка. Поле обязательно при типе `ACCOUNT` | +| **name** | string | Нет | Тип контрагента | +| **inn** | string | Нет | ИНН организации или физического лица | +| **kpp** | string | Нет | КПП организации (только для юридических лиц) | +| **isMain** | boolean | Нет | Признак основных реквизитов. По умолчанию для первых — `true`, для следующих — `false` | +| **digestSignatures** | array | Да | Электронная подпись УЛ клиента (список объектов) | +| └ **base64Encoded** | string | Да | Значение электронной подписи в Base64 | +| └ **signatureType** | string | Да | Тип подписи: `rsa` или `kep` | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "ООО Ромашка", + "inn": "1234567890", + "kpp": "123456789", + "isMain": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обяз. | Описание | +| :----------- | :------ | :---- | :-------------------------------------------- | +| **id** | string | Да | Идентификатор платёжного реквизита | +| **isMain** | boolean | Да | Признак основного реквизита (`true`/`false`) | +| **isActive** | boolean | Да | Признак активности реквизита (`true`/`false`) | + +**Пример ответа:** + +```json +{ + "id": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "isMain": true, + "isActive": true +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** +← [Создание запроса на проверку бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/beneficiary-scoring/v1/beneficiary-scoring) | [Получение платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-requisites/v1/get-requisites) → diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/beneficiary-scoring.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/beneficiary-scoring.md new file mode 100644 index 0000000..d4bd53b --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/beneficiary-scoring.md @@ -0,0 +1,90 @@ +# Создание запроса на проверку бенефициара + +**Метка:** `H2H` + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :------------------------------------------------------------------------------------ | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/scoring` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/scoring` | + +## Scope + +`beneficiaries` + +## Описание + +Метод позволяет проверить актуальность данных бенефициара по `beneficiaryId`. + +> **Важно** +> Если бенефициар не пройдет проверку, он будет деактивирован в системе. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | required | `application/json` | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------- | :------------- | :------------------------ | +| **beneficiaryId** | `string` | required | Идентификатор бенефициара | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request POST 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/scoring' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 202 (Accepted) + +Успешное принятие запроса в обработку. + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **requestId** | `string` | required | Идентификатор запроса | +| **status** | `string` | required | Статус запроса. Возможные значения:
• `PENDING` – запрос в процессе обработки;
• `FAILED` – обработка запроса завершилась ошибкой;
• `COMPLETE` – обработка запроса завершилась успешно | + +**Пример ответа:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +## Навигация + +- **Предыдущий метод:** [Создание запроса на изменение информации о бенефициаре](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-beneficiary/v1/change-beneficiary) +- **Следующий метод:** [Добавление платёжных реквизитов бенефициара](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-beneficiary.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-beneficiary.md new file mode 100644 index 0000000..a298ee9 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-beneficiary.md @@ -0,0 +1,151 @@ +# Создание запроса на изменение информации о бенефициаре + +**H2H** + +## Эндпоинты + +| Окружение | Метод и URL | +| :------------ | :--------------------------------------------------------------------------- | +| **Песочница** | `PUT https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}` | +| **Пром** | `PUT https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}` | + +### Scope + +`beneficiaries` + +### Описание + +Метод позволяет изменить информацию о бенефициаре по `beneficiaryId`. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Описание | +| :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization**
_string, required_ | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
_string, required_ | `application/json` | +| **Content-Type**
_string, required_ | `application/json` | + +### PATH + +| Атрибут | Описание | +| :---------------------------------------- | :------------------------ | +| **beneficiaryId**
_string, required_ | Идентификатор бенефициара | + +### BODY + +| Атрибут | Тип | Описание | +| :---------------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | +| **type** | _string, required_ | Тип контрагента. Возможные значения: | +| **name** | _string, optional_ | Наименование организации. Поле обязательно для бенефициаров с типом `UL_RESIDENT`. | +| **registrationDate** | _string, optional_ | Дата регистрации. Поле обязательно для бенефициаров с типом `UL_RESIDENT`. | +| **personalInformation** | _object, optional_ | Обновленные персональные данные. Заполняется для бенефициаров с типом `FL_RESIDENT`. | +| ∟ **firstName** | _string, optional_ | Имя | +| ∟ **middleName** | _string, optional_ | Отчество | +| ∟ **lastName** | _string, optional_ | Фамилия | +| ∟ **birthDate** | _string, optional_ | Дата рождения | +| ∟ **birthPlace** | _string, optional_ | Место рождения | +| **phoneNumber** | _string, optional_ | Телефон | +| **email** | _string, optional_ | Адрес электронной почты | +| **addresses** | _array of objects, optional_ | Адрес бенефициара | +| ∟ **type** | _string, required_ | Тип адреса: `REGISTRATION_ADDRESS` (адрес регистрации) или `LEGAL_ENTITY_ADDRESS` (адрес юр. лица). | +| ∟ **address** | _string, required_ | Строка адреса | +| **documents** | _array of objects, optional_ | Документы. Заполняется, если `citizenship` равен `RU`. | +| ∟ **type** | _string, required_ | Тип документа: `PASSPORT`, `FOREIGN_PASSPORT`, `RESIDENCE_PERMIT`, `STATELESS_RESIDENCE_CERTIFICATE`, `TEMPORARY_RESIDENCE_PERMIT`, `MIGRATION_CARD`. | +| ∟ **serial** | _string, required_ | Серия документа | +| ∟ **number** | _string, required_ | Номер документа | +| ∟ **issueDate** | _string, required_ | Дата выдачи | +| ∟ **division** | _string, required_ | Код подразделения | +| ∟ **organization** | _string, required_ | Орган, выдавший документ | +| **isActive** | _boolean, optional_ | Статус активности бенефициара | +| **digestSignatures** | _array of objects, required_ | Электронная подпись УЛ клиента | +| ∟ **base64Encoded** | _string, required_ | Значение электронной подписи в Base64 | +| ∟ **signatureType** | _string, required_ | Тип подписи: `rsa` или `kep`. | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff --request PUT 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data-raw '{ + "type": "FL_RESIDENT", + "name": "Акционерное общество «Ромашка»", + "registrationDate": "2025-12-23", + "personalInformation": { + "firstName": "Иван", + "middleName": "Иванoвич", + "lastName": "Иванов", + "birthDate": "2000-03-02", + "birthPlace": "Г. Иркутск" + }, + "phoneNumber": "79130000011", + "email": "IvanovIvan@mail.ru", + "addresses": [ + { + "type": "REGISTRATION_ADDRESS", + "address": "ул. Максима Горького 55" + } + ], + "documents": [ + { + "type": "PASSPORT", + "serial": "6953", + "number": "987435", + "issueDate": "2022-03-02", + "division": "123-321", + "organization": "ОВД Иркутской области по Г. Иркутску по Октябрьскому району" + } + ], + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +| Атрибут | Тип | Описание | +| :------------ | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| **requestId** | _string, required_ | Идентификатор запроса | +| **status** | _string, required_ | Статус запроса: | + +### Коды ошибок + +| Код | Описание | Тело ответа (основные атрибуты) | +| :------ | :------------------ | :------------------------------ | +| **400** | Bad Request | `error`: `invalid_request` | +| **401** | Unauthorized | `error`: `invalid_token` | +| **403** | Forbidden | `error`: `insufficient_scope` | +| **404** | Not Found | `error`: `unknown_endpoint` | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `error`: `internal_error` | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +### Навигация + +- [← Получение информации о бенефициаре](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-beneficiary/v1/get-beneficiary) +- [Создание запроса на проверку бенефициара →](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/beneficiary-scoring/v1/beneficiary-scoring) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-requisites.md new file mode 100644 index 0000000..4881052 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/change-requisites.md @@ -0,0 +1,134 @@ +# Изменение признаков платёжных реквизитов бенефициара + +**H2H** + +### Эндпоинты + +**Песочница** +`PATCH https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}` + +**Пром** +`PATCH https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}` + +--- + +### Scope + +`beneficiaries` + +### Описание + +Метод позволяет изменить признаки платёжных реквизитов бенефициара по `beneficiaryId` и `requisiteId`. + +> **Важно** +> Необходимо, чтобы хотя бы один из активных реквизитов бенефициара был основным. + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Content-Type** | string (required) | application/json | + +#### PATH + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :--------------------------------- | +| **beneficiaryId** | string (required) | Идентификатор бенефициара | +| **requisiteId** | string (required) | Идентификатор платёжного реквизита | + +#### BODY + +| Атрибут | Тип | Описание | +| :------------------- | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **pan** | string (optional) | Токен номера карты контрагента. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **keyId** | string (optional) | Идентификатор публичного ключа для расшифровки токена номера карты | +| **phoneNumber** | string (optional) | Номер телефона контрагента | +| **bankId** | string (optional) | Идентификатор банка контрагента | +| **accountNumber** | string (optional) | Номер счёта контрагента | +| **bik** | string (optional) | БИК банка контрагента | +| **isMain** | boolean (optional) | Признак основного платёжного реквизита.
• `true` - основной;
• `false` - неосновной | +| **isActive** | boolean (optional) | Признак активности платёжного реквизита.
• `true` - активен;
• `false` - деактивирован | +| **digestSignatures** | array of objects (required) | Электронная подпись УЛ клиента | + +**Объект digestSignatures:** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **base64Encoded** | string (required) | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string (required) | Тип электронной подписи:
• `rsa` - RSA;
• `kep` - КЭП | + +--- + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--data '{ + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "keyId": "1", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "isMain": true, + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +**204 No Content** +_Нет тела ответа_ + +**400 Bad Request** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `invalid_request` — неверные входные параметры запроса | +| **error_description** | string (optional) | Описание ошибки | + +**401 Unauthorized** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `invalid_token` — токен просрочен, отозван или недействителен | + +**403 Forbidden** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `insufficient_scope` — у пользователя нет прав на использование сервиса | + +**404 Not Found** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `unknown_endpoint` — эндпоинт не найден или неактивен | + +**429 Too Many Requests** +_Превышен лимит запросов. Нет тела ответа._ + +**500 Internal Server Error** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `internal_error` — внутренняя ошибка сервиса | + +**503 Service Unavailable** +_Сервис временно недоступен._ + +--- + +**Навигация:** + +- Предыдущая статья: [Получение платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-requisites/v1/get-requisites) +- Следующая статья: [Получение информации о балансе бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-balance/v1/get-balance) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-balance.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-balance.md new file mode 100644 index 0000000..713021f --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-balance.md @@ -0,0 +1,139 @@ +# Получение информации о балансе бенефициара + +**Метка:** `H2H` + +## Эндпоинты + +### Песочница + +`GET https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/balance` + +### Пром + +`GET https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/balance` + +--- + +## Scope + +`beneficiaries` + +## Описание + +Метод позволяет получить баланс счёта бенефициара по `beneficiaryId` на определённую дату. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :------------- | +| **Authorization** | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | string | required | +| **Accept** | application/json | string | required | + +### QUERY + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :----------------------- | :----- | :------------- | +| **accountNumber** | Номер номинального счёта | string | required | +| **date** | Дата | string | required | + +### PATH + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :------------------------ | :----- | :------------- | +| **beneficiaryId** | Идентификатор бенефициара | string | required | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/balance?accountNumber=40817810306050000000&date=2024-01-01' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 (OK) — Тело ответа (BODY) + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :------------------------ | :--------------- | :------------- | +| **beneficiaryId** | Идентификатор бенефициара | string | required | +| **accountNumber** | Номер счёта | string | required | +| **date** | Дата | string | required | +| **balances** | Балансы бенефициара | array of objects | optional | + +#### Вложенные атрибуты `balances`: + +- **walletType** (string, optional): Тип кошелька. Принимает значения: + - `MAIN` — основной кошелек; + - `TAX` — налоговый кошелек. +- **freeBalance** (string, optional): Свободные денежные средства в рублях. +- **heldBalance** (string, optional): Захолдированные денежные средства в рублях. + +#### Пример ответа 200: + +```json +{ + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "accountNumber": "40817810306050000000", + "date": "2024-01-01", + "balances": [ + { + "walletType": "MAIN", + "freeBalance": "10.00", + "heldBalance": "10.00" + } + ] +} +``` + +--- + +## Ошибки + +### 400 (Bad Request) + +- **error** (string): `invalid_request` — неверные входные параметры запроса. +- **error_description** (string, optional): Описание ошибки. + +### 401 (Unauthorized) + +- **error** (string): `invalid_token` — предоставленный токен просрочен, отозван или недействителен. +- **error_description** (string, optional): Описание ошибки. + +### 403 (Forbidden) + +- **error** (string): `insufficient_scope` — у пользователя нет прав на использование запрашиваемого сервиса. +- **error_description** (string, optional): Описание ошибки. + +### 404 (Not Found) + +- **error** (string): `unknown_endpoint` — эндпоинт не найден или неактивен. +- **error_description** (string, optional): Описание ошибки. + +### 429 (Too Many Requests) + +- Тело ответа отсутствует. + +### 500 (Internal Server Error) + +- **error** (string): `internal_error` — внутренняя ошибка сервиса. +- **error_description** (string, optional): Описание ошибки. + +### 503 (Service Unavailable) + +- Тело ответа отсутствует. + +--- + +**Навигация:** + +- Предыдущий метод: [Изменение признаков платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-requisites/v1/change-requisites) +- Следующий метод: [Получение списка денежных операций бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-transactions/v1/get-transactions) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiaries.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiaries.md new file mode 100644 index 0000000..4747031 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiaries.md @@ -0,0 +1,120 @@ +Вот обновленное, максимально полное и структурированное описание API в формате Markdown. Я добавил детали из всех скриншотов, расширил описание ошибок и структурировал данные для лучшей читаемости. + +--- + +# Получение списка бенефициаров номинального счёта + +**Тип интеграции:** H2H (Host-to-Host) +**Раздел:** [Номинальные счета](#) / Получение списка бенефициаров номинального счёта + +## 1. Общая информация + +Метод позволяет получить подробный список всех бенефициаров, привязанных к конкретному номинальному счёту, с возможностью фильтрации и пагинации. + +### Конечные точки (Endpoints) + +| Среда | Метод | URL | +| :--- | :--- | :--- | +| **Песочница** | `GET` | `https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries` | +| **Пром** | `GET` | `https://baas.alfabank.ru/api/na/jp/v1/beneficiaries` | + +**Требуемый Scope:** `beneficiaries` + +--- + +## 2. Параметры запроса + +### Заголовки (Headers) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | `STRING` | Да | `Bearer {access_token}`, полученный по схеме Authorization Code Flow H2H. | +| **Accept** | `STRING` | Да | Должен быть `application/json`. | + +### Параметры строки запроса (Query) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **accountNumber** | `STRING` | **Да** | Номер номинального счёта (20 знаков). | +| **type** | `STRING` | **Да** | Тип бенефициара: `FL_RESIDENT`, `FL_NONRESIDENT`, `UL_RESIDENT`, `UL_NONRESIDENT`, `IP_RESIDENT`, `IP_NONRESIDENT`. | +| **limit** | `INTEGER` | Нет | Кол-во объектов на странице (по умолчанию обычно 100). | +| **offset** | `INTEGER` | Нет | Смещение (кол-во пропускаемых объектов). | +| **inn** | `STRING` | Нет | ИНН (10 цифр для ЮЛ, 12 — для ФЛ/ИП). | +| **lastName** | `STRING` | Нет | Фамилия (для ФЛ и ИП). | +| **firstName** | `STRING` | Нет | Имя (для ФЛ и ИП). | +| **middleName** | `STRING` | Нет | Отчество (для ФЛ и ИП). | +| **kpp** | `STRING` | Нет | КПП (только для `UL_RESIDENT`). | +| **name** | `STRING` | Нет | Название организации (для ЮЛ). | +| **ogrn** | `STRING` | Нет | ОГРН (только для `UL_RESIDENT`). | +| **isVpr** | `BOOLEAN` | Нет | `true` — является выгодоприобретателем, `false` — нет. | +| **isActive** | `BOOLEAN` | Нет | Статус: `true` — активен, `false` — деактивирован. | +| **date** | `STRING` | Нет | Дата выборки. | + +**Пример вызова (cURL):** +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries?accountNumber=40817810306050000000&type=FL_RESIDENT' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## 3. Параметры ответа (200 OK) + +В случае успеха возвращается объект со списком бенефициаров и данными пагинации. + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **pagination** | `OBJECT` | Информация о страницах: `limit`, `offset`, `totalCount`. | +| **accountNumber**| `STRING` | Номер счёта, по которому сделан запрос. | +| **beneficiaries** | `ARRAY` | Массив объектов бенефициаров (включает ФИО, ИНН, адреса, документы и балансы). | + +--- + +## 4. Обработка ошибок + +Ниже приведен полный перечень возможных ошибок с описанием их причин. + +### Сводная таблица кодов +| Код | Описание | Тело ответа | +| :--- | :--- | :--- | +| **400** | Bad Request | Ошибка в параметрах запроса. | +| **401** | Unauthorized | Проблемы с токеном доступа. | +| **403** | Forbidden | Недостаточно прав (Scope). | +| **404** | Not Found | Ресурс или эндпоинт не найден. | +| **429** | Too Many Requests | Превышен лимит запросов (без тела). | +| **500** | Internal Server Error | Внутренняя ошибка сервера. | +| **503** | Service Unavailable | Сервис временно недоступен (без тела). | + +--- + +### Детальное описание бизнес-ошибок + +#### 400 Bad Request +Возникает при передаче невалидных данных (например, неверный формат номера счета). +* `error`: `invalid_request` +* `error_description`: Описание конкретной ошибки валидации. + +#### 401 Unauthorized +Проблема с авторизационным заголовком или самим токеном. +* `error`: `invalid_token` +* `error_description`: Предоставленный токен просрочен, отозван, имеет неправильный формат или недействителен. + +#### 403 Forbidden +Доступ к методу ограничен настройками безопасности. +* `error`: `insufficient_scope` +* `error_description`: У пользователя нет прав на использование сервиса (отсутствует нужный scope в токене). + +#### 404 Not Found +Запрашиваемый адрес API не существует или отключен. +* `error`: `unknown_endpoint` +* `error_description`: Эндпоинт не найден или неактивен. + +#### 500 Internal Server Error +Непредвиденная ошибка на стороне банка. +* `error`: `internal_error` +* `error_description`: Внутренняя ошибка сервиса при выполнении обработки запроса. + +--- + +## 5. Навигация + +← [Создание запроса на регистрацию бенефициара](#) | [Получение информации о бенефициаре](#) → diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiary.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiary.md new file mode 100644 index 0000000..407a223 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-beneficiary.md @@ -0,0 +1,178 @@ +Вот преобразованная документация в формате Markdown. Я сохранил структуру, таблицы параметров, примеры кода и ссылки. + +--- + +# Получение информации о бенефициаре `H2H` + +Метод позволяет получить информацию о бенефициаре по `beneficiaryId`. + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}` | + +## Scope +`beneficiaries` + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | application/json | + +### PATH +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **beneficiaryId** | string | Да | Идентификатор бенефициара | + +### Пример запроса (cURL) +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +#### Пример тела ответа +```json +{ + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "type": "FL_RESIDENT", + "personalInformation": { + "inn": "112233445566", + "firstName": "Иван", + "middleName": "Иванoвич", + "lastName": "Иванов", + "citizenship": "RU", + "birthDate": "2000-03-02", + "birthPlace": "Г. Иркутск", + "snils": 12345678910 + }, + "countryOfTaxResidence": "RU", + "phoneNumber": "79130000011", + "email": "IvanovIvan@mail.ru", + "addresses": [ + { + "type": "REGISTRATION_ADDRESS", + "address": "ул. Пушкина 55", + "index": "123456", + "region_code": "77", + "uin": "550e8400-e29b-41d4-a716-446655440000", + "municipal_district": { + "type_code": 1, + "name": "Ленинский муниципальный район" + }, + "settlement": { + "type_code": 1, + "name": "Городское поселение Ленинское" + }, + "locality": { + "type": "город", + "name": "Ленинск" + }, + "planning_structure": { + "type": "микрорайон", + "name": "Центральный" + }, + "street_network": { + "type": "улица", + "name": "Ленина" + }, + "buildings": [ + { + "type": "дом", + "name": "3" + } + ], + "building_premises": { + "type": "квартира", + "name": "42" + }, + "flat_premises": { + "type": "комната", + "name": "гостиная" + } + } + ], + "documents": [ + { + "type": "PASSPORT", + "serial": "6953", + "number": "987435", + "issueDate": "2022-03-02", + "expireDate": "2022-03-02", + "division": "123-321", + "organization": "ОВД Иркутской области по Г. Иркутску по Октябрьскому району" + } + ], + "name": "Акционерное общество «Ромашка»", + "registrationDate": "2025-12-18", + "inn": "0123456789", + "kpp": "0123456789", + "ogrn": "0123456789101", + "isActive": true, + "actualizationDateExpire": "2025-12-18", + "balances": [ + { + "walletType": "MAIN", + "freeBalance": "10.00", + "heldBalance": "10.00" + } + ], + "isBeneficiary": true, + "isVpr": true +} +``` + +#### Описание полей (BODY) + +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **beneficiaryId** | string | Идентификатор бенефициара | +| **type** | string | Тип контрагента: `FL_RESIDENT`, `FL_NONRESIDENT`, `UL_RESIDENT`, `UL_NONRESIDENT`, `IP_RESIDENT`, `IP_NONRESIDENT` | +| **personalInformation** | object | Персональные данные (только для ФЛ и ИП) | +| ∟ **inn** | string | ИНН | +| ∟ **firstName** | string | Имя | +| ∟ **lastName** | string | Фамилия | +| ∟ **citizenship** | string | Гражданство: `RU`, `BY`, `AM`, `KZ`, `KG` | +| **countryOfTaxResidence**| string | Страна налогового резидентства (ISO 3166-1 alpha-2) | +| **addresses** | array | Список адресов | +| ∟ **type** | string | `REGISTRATION_ADDRESS`, `RESIDENCE_ADDRESS`, `LEGAL_ENTITY_ADDRESS` | +| **documents** | array | Список документов (Для резидентов обязателен `PASSPORT`) | +| **name** | string | Наименование организации (для UL) | +| **isActive** | boolean | Статус активности бенефициара (`true`/`false`) | +| **balances** | array | Балансы бенефициара | +| ∟ **walletType** | string | Тип кошелька: `MAIN` (основной), `TAX` (налоговый) | +| **isBeneficiary** | boolean | `true` — бенефициар, `false` — универсальный реципиент | +| **isVpr** | boolean | Признак выгодоприобретателя (ВПР) | + +--- + +## Ошибки + +| Код | Описание | Возможные причины (`error`) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (проверьте scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Превышен лимит запросов (нет тела ответа) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Сервис временно недоступен | + +--- + +**Навигация:** +* [← Получение списка бенефициаров номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-beneficiaries/v1/get-beneficiaries) +* [Создание запроса на изменение информации о бенефициаре →](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-beneficiary/v1/change-beneficiary) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-requisites.md new file mode 100644 index 0000000..79916b2 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-requisites.md @@ -0,0 +1,108 @@ +# Получение платёжных реквизитов бенефициара + +tags: `H2H` + +**Продукт:** Номинальные счета / Бенефициары +**Scope:** beneficiaries + +--- + +## Эндпоинты + +**Песочница:** +`GET https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites` + +**Пром:** +`GET https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites` + +--- + +## Описание + +Метод позволяет получить платёжные реквизиты бенефициара по идентификатору `beneficiaryId`. + +--- + +## Параметры запроса + +### Заголовки (Headers) + +| Атрибут | Описание | +| :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** (string, required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** (string, required) | application/json | + +### Путь (PATH) + +| Атрибут | Описание | +| :----------------------------------- | :------------------------ | +| **beneficiaryId** (string, required) | Идентификатор бенефициара | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ: 200 (OK) + +**Пример тела ответа:** + +```json +[ + { + "Id": "cba2888c-71ad-4211-9420-a85f6e4c10f9", + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "isMain": true, + "isActive": true + } +] +``` + +**Описание полей (BODY):** + +| Атрибут | Тип | Описание | +| :---------------- | :----------------- | :----------------------------------------------------------------------------------------- | +| **Id** | string (required) | Идентификатор платёжного реквизита | +| **type** | string (required) | Тип платёжного реквизита: ACCOUNT (счёт), CARD (номер карты/токен), PHONE (номер телефона) | +| **pan** | string (optional) | Токен номера карты. Заполняется при типе CARD | +| **phoneNumber** | string (optional) | Номер телефона. Заполняется при типе PHONE | +| **bankId** | string (optional) | Идентификатор банка контрагента-получателя. Заполняется при типе PHONE | +| **accountNumber** | string (optional) | Номер счёта. Заполняется при типе ACCOUNT | +| **bik** | string (optional) | БИК банка. Заполняется при типе ACCOUNT | +| **isMain** | boolean (required) | Признак основного реквизита: true — основной, false — неосновной | +| **isActive** | boolean (required) | Признак активности: true — активен, false — деактивирован | + +--- + +## Ошибки + +| Код | Статус | Код ошибки (error) и описание | +| :------ | :------------------ | :------------------------------------------------------ | +| **400** | Bad Request | invalid_request — неверные входные параметры | +| **401** | Unauthorized | invalid_token — токен недействителен или просрочен | +| **403** | Forbidden | insufficient_scope — нет прав доступа к сервису (scope) | +| **404** | Not Found | unknown_endpoint — эндпоинт не найден | +| **429** | Too Many Requests | Превышено количество запросов (без тела ответа) | +| **500** | Internal Error | internal_error — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Сервис временно недоступен (без тела ответа) | + +--- + +**Навигация:** + +- [Добавление платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites) +- [Изменение признаков платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-requisites/v1/change-requisites) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-transactions.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-transactions.md new file mode 100644 index 0000000..f35c5af --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Бенефициары/get-transactions.md @@ -0,0 +1,109 @@ +# Получение списка денежных операций бенефициара + +**Тип интеграции:** H2H +**Scope:** `beneficiaries` + +## Описание +Метод позволяет получить список денежных операций бенефициара за заданный период по `beneficiaryId`. + +--- + +## Эндпоинты + +| Среда | URL | +| :--- | :--- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/transactions` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/transactions` | + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | + +### QUERY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **limit** | integer | required | Количество объектов на одной странице | +| **offset** | integer | required | Количество объектов в списке, которые необходимо пропустить | +| **dateFrom** | string | required | Дата начала выборки (ГГГГ-ММ-ДД) | +| **dateTo** | string | required | Дата конца выборки (ГГГГ-ММ-ДД) | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **beneficiaryId** | string | required | Идентификатор бенефициара | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/transactions?limit=100&offset={offset}&dateFrom=2024-01-01&dateTo=2024-01-01' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK +#### BODY (Object) +* **pagination** (object, optional): Данные пагинации + * **limit** (number, optional): Количество записей на одной странице + * **offset** (number, optional): Количество записей в списке, которые были пропущены + * **totalCount** (number, optional): Общее количество записей +* **transactionsList** (array of objects, optional): Список операций + * **type** (string, required): Тип операции. Возможные значения: + * `Пополнение` — увеличение денежных средств бенефициара на номинальном счёте; + * `Вывод` — уменьшение денежных средств бенефициара на номинальном счёте; + * `Заморозка` — холдирование денежных средств бенефициара на номинальном счёте; + * `Разморозка` — расхолдирование замороженных денежных средств бенефициара на номинальном счёте; + * `Исходящий перевод` — перевод денежных средств другому бенефициару; + * `Входящий перевод` — поступление денежных средств от другого бенефициара. + * **amount** (string, required): Сумма операции в рублях. + * **comment** (string, optional): Комментарий к операции. + +### Пример ответа 200 + +```json +{ + "pagination": { + "limit": 100, + "offset": 0, + "totalCount": 10000 + }, + "transactionsList": [ + { + "type": "Пополнение", + "amount": "10.00", + "comment": "Ручное выравнивание баланса" + } + ] +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error / error_description) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (не настроен scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** +* Предыдущий метод: [Получение информации о балансе бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-balance/v1/get-balance) +* Следующий раздел: [Создание запроса на регистрацию универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-ur/v1/add-ur) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-requisites.md new file mode 100644 index 0000000..8f76bd4 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-requisites.md @@ -0,0 +1,117 @@ +# Добавление платёжных реквизитов универсального реципиента + +**Тип интеграции:** H2H + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites` | + +## Scope +`beneficiaries` + +## Описание +Метод позволяет добавить платёжные реквизиты универсального реципиента по `universalRecipientId`. + +> **Важно** +> Первые добавленные реквизиты автоматически назначаются основными для универсального реципиента. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **Authorization** | `string` (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` (required) | application/json | +| **Content-Type** | `string` (required) | application/json | + +### PATH +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **universalRecipientId** | `string` (required) | Идентификатор универсального реципиента | + +### BODY +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **type** | `string` (required) | Тип платёжного реквизита. Возможные значения:
• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | +| **pan** | `string` (optional) | Токен номера карты. Поле обязательно при типе реквизитов `CARD`. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **phoneNumber** | `string` (optional) | Номер телефона. Поле обязательно при типе реквизитов `PHONE` | +| **bankId** | `string` (optional) | Идентификатор банка контрагента-получателя. Поле обязательно при типе реквизитов `PHONE` | +| **accountNumber** | `string` (optional) | Номер счёта. Поле обязательно при типе реквизитов `ACCOUNT` | +| **bik** | `string` (optional) | БИК банка. Поле обязательно при типе реквизитов `ACCOUNT` | +| **name** | `string` (required) | Наименование получателя. Наименование организации (для юр. лиц), либо ФИО (для физ. лиц и ИП) | +| **inn** | `string` (required) | ИНН получателя. 10 цифр — для юр.лиц, 12 цифр — для физ.лиц и ИП | +| **kpp** | `string` (optional) | КПП получателя. Поле обязательно, если тип универсального реципиента `UL_RESIDENT` | +| **isMain** | `boolean` (optional) | Признак основных платежных реквизитов. По умолчанию для первых реквизитов — `true`, для последующих — `false`. | +| **digestSignatures** | `array of objects` (required) | Электронная подпись УЛ клиента | +| **└ base64Encoded** | `string` (required) | Значение электронной подписи, закодированное в Base64 | +| **└ signatureType** | `string` (required) | Тип электронной подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "isMain": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 200 (OK) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **id** | `string` (required) | Идентификатор платёжного реквизита | +| **isMain** | `boolean` (required) | Признак основного платёжного реквизита (`true` — основной, `false` — неосновной) | +| **isActive** | `boolean` (required) | Признак активности платёжного реквизита (`true` — активен, `false` — деактивирован) | + +**Пример ответа 200:** +```json +{ + "id": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "isMain": true, + "isActive": true +} +``` + +### Ошибки +| Код | Описание | Текст ошибки (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* [Предыдущая: Получение информации об универсальном реципиенте](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-ur/v1/get-ur) +* [Следующая: Получение платёжных реквизитов универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-requisites/v1/get-requisites) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-universal_recipient.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-universal_recipient.md new file mode 100644 index 0000000..607293b --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/add-universal_recipient.md @@ -0,0 +1,103 @@ +# Создание запроса на регистрацию универсального реципиента + +**Тип интеграции:** H2H + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `POST https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients` | +| **Пром** | `POST https://baas.alfabank.ru/api/na/jp/v1/universal-recipients` | + +### Scope +`beneficiaries` + +--- + +## Описание +Метод позволяет зарегистрировать универсального реципиента (контрагента с признаком `isBeneficiary = FALSE`) в системе. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### BODY +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **accountNumber** | string | Да | Номер номинального счёта | +| **type** | string | Да | Тип универсального реципиента. Возможные значения:
• `FL_RESIDENT` — физ. лицо, резидент;
• `UL_RESIDENT` — юр. лицо, резидент | +| **digestSignatures** | array of objects | Да | Электронная подпись УЛ клиента | + +**Объект digestSignatures:** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **base64Encoded** | string | Да | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string | Да | Тип электронной подписи. Возможные значения:
• `rsa` — RSA;
• `kep` — КЭП | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accountNumber": "40817810306050000000", + "type": "FL_RESIDENT", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ: 202 (Accepted) + +**Пример тела ответа:** +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +**Описание атрибутов:** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **requestId** | string | Да | Идентификатор запроса | +| **status** | string | Да | Статус запроса. Принимает значения:
• `PENDING` – запрос в процессе обработки;
• `FAILED` – ошибка обработки;
• `COMPLETE` – успешно завершено | + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** +* Предыдущая статья: [Получение списка денежных операций бенефициара](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-transactions/v1/get-transactions) +* Следующая статья: [Получение списка универсальных реципиентов номинального счёта](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-urs/v1/get-urs) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/change-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/change-requisites.md new file mode 100644 index 0000000..a6ba329 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/change-requisites.md @@ -0,0 +1,127 @@ +# Изменение признаков платёжных реквизитов универсального реципиента + +**Тип интеграции:** H2H + +--- + +## Эндпоинты + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `PATCH https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}` | +| **Пром** | `PATCH https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}` | + +--- + +## Общая информация + +* **Scope:** `beneficiaries` +* **Описание:** Метод позволяет изменить признаки платёжных реквизитов универсального реципиента по `universalRecipientId` и `requisiteId`. + +> **Важно:** Необходимо, чтобы хотя бы один из активных реквизитов универсального реципиента был основным. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Content-Type** | string | required | `application/json` | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **universalRecipientId** | string | required | Идентификатор универсального реципиента | +| **requisiteId** | string | required | Идентификатор платёжного реквизита | + +### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **pan** | string | optional | Токен номера карты контрагента. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **keyId** | string | optional | Идентификатор публичного ключа для расшифровки токена номера карты | +| **phoneNumber** | string | optional | Номер телефона контрагента | +| **bankId** | string | optional | Идентификатор банка контрагента | +| **accountNumber** | string | optional | Номер счета контрагента | +| **bik** | string | optional | БИК банка контрагента | +| **name** | string | optional | Наименование получателя | +| **inn** | string | optional | ИНН получателя | +| **kpp** | string | optional | КПП получателя | +| **isMain** | boolean | optional | Признак основного платёжного реквизита: `true` — основной; `false` — неосновной | +| **isActive** | boolean | optional | Признак активности платёжного реквизита: `true` — активен; `false` — деактивирован | +| **digestSignatures** | array of objects | **required** | Электронная подпись УЛ клиента (см. ниже) | + +#### Струтура объекта digestSignatures: +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **base64Encoded** | string | required | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string | required | Тип электронной подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--data '{ + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "keyId": "1", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "isMain": true, + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 204 No Content +Успешное выполнение запроса. Тело ответа отсутствует. + +### 400 Bad Request +| Атрибут | Описание | +| :--- | :--- | +| **error** | `invalid_request` — неверные входные параметры запроса | +| **error_description** | Описание ошибки | + +### 401 Unauthorized +| Атрибут | Описание | +| :--- | :--- | +| **error** | `invalid_token` — токен просрочен, отозван или недействителен | + +### 403 Forbidden +| Атрибут | Описание | +| :--- | :--- | +| **error** | `insufficient_scope` — нет прав (проверьте настройки scope) | + +### 404 Not Found +| Атрибут | Описание | +| :--- | :--- | +| **error** | `unknown_endpoint` — эндпоинт не найден или неактивен | + +### 429 Too Many Requests +Превышен лимит запросов. Тело ответа отсутствует. + +### 500 Internal Server Error +| Атрибут | Описание | +| :--- | :--- | +| **error** | `internal_error` — внутренняя ошибка сервиса | + +### 503 Service Unavailable +Сервис временно недоступен. Тело ответа отсутствует. diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-requisites.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-requisites.md new file mode 100644 index 0000000..ffc68af --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-requisites.md @@ -0,0 +1,88 @@ +# Получение платёжных реквизитов универсального реципиента + +**H2H** + +## Эндпоинты + +| Среда | Метод и URL | +| :--- | :--- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites` | + +## Scope +`beneficiaries` + +## Описание +Метод позволяет получить платёжные реквизиты универсального реципиента по `universalRecipientId`. + +## Параметры запроса + +### HEADERS +| Атрибут | Описание | Тип | Обязательность | +| :--- | :--- | :--- | :--- | +| **Authorization** | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | string | required | +| **Accept** | application/json | string | required | + +### PATH +| Атрибут | Описание | Тип | Обязательность | +| :--- | :--- | :--- | :--- | +| **universalRecipientId** | Идентификатор универсального реципиента | string | required | + +### Пример запроса (cURL) +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK (Пример тела ответа) +```json +[ + { + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "isMain": true, + "isActive": true + } +] +``` + +### BODY (Описание полей) +| Атрибут | Описание | Тип | Обязательность | +| :--- | :--- | :--- | :--- | +| **type** | Тип платёжного реквизита. Возможные значения:
• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | string | required | +| **pan** | Токен номера карты. Возвращается, если тип реквизитов `CARD` | string | optional | +| **phoneNumber** | Номер телефона. Возвращается, если тип реквизитов `PHONE` | string | optional | +| **bankId** | Идентификатор банка контрагента-получателя. Возвращается, если тип реквизитов `PHONE` | string | optional | +| **accountNumber** | Номер счёта. Возвращается, если тип реквизитов `ACCOUNT` | string | optional | +| **bik** | БИК банка. Возвращается, если тип реквизитов `ACCOUNT` | string | optional | +| **name** | Наименование получателя. Наименование организации (для ЮЛ), либо ФИО (для ФЛ и ИП) | string | required | +| **inn** | ИНН получателя (10 цифр для ЮЛ, 12 цифр для ФЛ и ИП) | string | required | +| **kpp** | КПП получателя. Возвращается, если тип универсального реципиента `UL_RESIDENT` | string | optional | +| **isMain** | Признак основного платёжного реквизита:
• `true` — основной;
• `false` — неосновной | boolean | required | +| **isActive** | Признак активности платёжного реквизита:
• `true` — активен;
• `false` — деактивирован | boolean | required | + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipient.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipient.md new file mode 100644 index 0000000..4ac79da --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipient.md @@ -0,0 +1,115 @@ +# Получение информации об универсальном реципиенте + +**Тип интеграции:** H2H +**Продукт:** Номинальные счета + +--- + +## Эндпоинты + +| Среда | URL | +| :--- | :--- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}` | + +--- + +## Scope +`beneficiaries` + +--- + +## Описание +Метод позволяет получить информацию об универсальном реципиенте по `universalRecipientId`. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | application/json | + +### PATH +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **universalRecipientId** | string | Да | Идентификатор универсального реципиента | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 (OK) — Тело ответа (BODY) + +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **universalRecipientId** | string | Да | Идентификатор универсального реципиента | +| **accountNumber** | string | Да | Номер номинального счёта | +| **isBeneficiary** | boolean | Да | Признак бенефициара:
• `true` — является бенефициаром;
• `false` — является универсальным реципиентом. | +| **type** | string | Да | Тип контрагента:
• `FL_RESIDENT` — физ. лицо, резидент;
• `UL_RESIDENT` — юр. лицо, резидент. | +| **isActive** | boolean | Да | Признак активности бенефициара:
• `true` — активен;
• `false` — деактивирован. | + +**Пример успешного ответа:** +```json +{ + "universalRecipientId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "accountNumber": "40817810306050000000", + "isBeneficiary": false, + "type": "FL_RESIDENT", + "isActive": true +} +``` + +--- + +## Ошибки + +### 400 — Bad Request +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | Нет | Описание ошибки | + +### 401 — Unauthorized +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `invalid_token` — токен просрочен, отозван или неверный формат | + +### 403 — Forbidden +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `insufficient_scope` — нет прав на использование сервиса (настройки scope) | + +### 404 — Not Found +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `unknown_endpoint` — эндпоинт не найден или неактивен | + +### 429 — Too Many Requests +Нет тела ответа. Слишком много запросов. + +### 500 — Internal Server Error +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `internal_error` — внутренняя ошибка сервиса | + +### 503 — Service Unavailable +Нет тела ответа. Сервис временно недоступен. + +--- + +## Навигация +* **Назад:** [Получение списка универсальных реципиентов номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-urs/v1/get-urs) +* **Вперед:** [Добавление платёжных реквизитов универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-requisites/v1/add-requisites) diff --git a/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipients_list.md b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipients_list.md new file mode 100644 index 0000000..54d7a36 --- /dev/null +++ b/_docs/alfabank/payin_and_kyc/продукты_и_сервисы/Номинальные_счета/Контрагенты/Универсальные_реципиенты/get-universal_recipients_list.md @@ -0,0 +1,110 @@ +# Получение списка универсальных реципиентов номинального счёта + +**Тип интеграции:** H2H + +--- + +## Конечные точки (Endpoints) + +| Окружение | Метод и URL | +| :--- | :--- | +| **Песочница** | `GET https://sandbox.alfabank.ru/api/na/jp/v1/universal-recipients` | +| **Пром** | `GET https://baas.alfabank.ru/api/na/jp/v1/universal-recipients` | + +--- + +## Scope +`beneficiaries` + +## Описание +Метод позволяет получить список универсальных реципиентов номинального счёта. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | + +### QUERY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **limit** | integer | optional | Количество объектов на одной странице | +| **offset** | integer | optional | Количество объектов в списке, которые необходимо пропустить | +| **accountNumber** | string | required | Номер номинального счёта | +| **type** | string | required | Тип универсального реципиента. Возможные значения: `FL_RESIDENT` (физ. лицо), `UL_RESIDENT` (юр. лицо), `IP_RESIDENT` (ИП) | +| **isActive** | boolean | optional | Признак активности: `true` — активен; `false` — деактивирован | +| **date** | string | optional | Дата выборки | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients?limit=100&offset={offset}&accountNumber=40817810306050000000&type={type}&isActive={isActive}&date=2024-01-01' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Пример тела ответа:** +```json +{ + "pagination": { + "limit": 100, + "offset": 0, + "totalCount": 1 + }, + "accountNumber": "40817810306050000000", + "date": "2024-01-01", + "universalRecipients": [ + { + "universalRecipientId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "isBeneficiary": false, + "type": "FL_RESIDENT", + "isActive": true + } + ] +} +``` + +**Описание полей BODY:** +* **pagination** (object, optional): Данные пагинации. + * `limit` (number): Количество записей на странице. + * `offset` (number): Количество пропущенных записей. + * `totalCount` (number): Общее количество записей. +* **accountNumber** (string, required): Номер номинального счёта. +* **date** (string, optional): Дата. +* **universalRecipients** (array of objects, required): Информация об универсальных реципиентах. + * `universalRecipientId` (string): Идентификатор реципиента. + * `isBeneficiary` (boolean): `true` — бенефициар, `false` — универсальный реципиент. + * `type` (string): Тип контрагента (`FL_RESIDENT`, `UL_RESIDENT`). + * `isActive` (boolean): Статус активности. + +--- + +## Ошибки + +| Код | Описание | Код ошибки (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Превышен лимит запросов (нет тела ответа) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Сервис временно недоступен (нет тела ответа) | + +--- + +## Навигация по разделу +* **Назад:** [Создание запроса на регистрацию универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-ur/v1/add-ur) +* **Далее:** [Получение информации об универсальном реципиенте](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-ur/v1/get-ur) diff --git a/_docs/alfabank/qr_payout/0_full.md b/_docs/alfabank/qr_payout/0_full.md new file mode 100644 index 0000000..8f62cd6 --- /dev/null +++ b/_docs/alfabank/qr_payout/0_full.md @@ -0,0 +1,1462 @@ +## Главная +### Инструкция по интеграции СБП C2B (Альфа-Банк) + +Добро пожаловать в руководство по прямой интеграции с платежным шлюзом (ПШ) Альфа-Банка для реализации сервиса СБП C2B. + +--- + +### ⚠️ Важное объявление (Изменение адресов) +С **01.11.2024** адрес тестового стенда изменен. Старые адреса недоступны. + +* **Новый URL тестового стенда:** `https://217.12.103.132:2443/fsCryptoProxy` +* **Условие доступа:** Обязательное установление **MTLS соединения**. + +--- + +### 1. Обзор API + +Взаимодействие с платежным шлюзом Альфа-Банка строится на следующих принципах: + +| Параметр | Описание | +| :--- | :--- | +| **Протокол** | HTTPS | +| **Архитектура** | REST | +| **Методы** | POST | +| **Формат данных** | JSON (аргументы и ответы) | +| **Кодировка текста** | urlencoded (внутри JSON ответов) | +| **Поддержка** | [acquiring@alfabank.ru](mailto:acquiring@alfabank.ru) | + +#### Особенности обработки ошибок +* Каждый ответ содержит поле `ErrorCode`. +* При возникновении логической ошибки описание возвращается в поле `message`. + +--- + +## 2. Процесс аутентификации + +Для работы со шлюзом (и на тестовой, и на промышленной среде) используется двусторонняя аутентификация **MTLS** и подпись тела запроса. + +### 2.1. Генерация сертификатов (Self-signed) +Клиент должен самостоятельно сгенерировать ключевую пару RSA для подписи запросов. + +**Команда OpenSSL:** +```bash +openssl req -x509 -newkey rsa:4096 -keyout private.key -out client.crt -nodes -days 3650 +``` + +**Рекомендуемые параметры заполнения:** +* **Country (RU)**, **City (Moscow)**, **Organization (Ваша компания)**. +* **Common Name:** Company Pay C2B. +* **Срок действия:** не менее 10 лет. +* **Длина ключа:** 2048 или 4096 бит. + +### 2.2. Регистрация в банке +Файл `client.crt` необходимо отправить на [acquiring@alfabank.ru](mailto:acquiring@alfabank.ru). + +**Шаблон письма:** +> **Тема:** Регистрация сертификата на [тестовом/промышленном] стенде СБП C2B +> +> **Тело:** +> Просим зарегистрировать сертификат для работы с СБП C2B. +> * **Тип регистрации:** Впервые / Повторно (взамен истёкшего alias...) +> * **Организация:** [Название] +> * **ИНН:** [Номер] +> * **Вложение:** client.crt (в архиве без пароля) + +### 2.3. Что вы получите от банка +После регистрации банк предоставит: +1. **Alias** — имя вашего сертификата (передается в заголовке `key-name`). +2. **Клиентский сертификат RSA/TLS** — для поднятия MTLS-соединения. +3. **Корневые сертификаты банка** — для проверки серверного сертификата. +4. **TermNo** — тестовый номер терминала. +5. **Эндпойнт** — для промышленной среды. + +--- + +## 3. Техническая реализация запроса + +### 3.1. Формирование заголовков (Headers) +При каждом запросе необходимо передавать следующие заголовки: + +| Заголовок | Значение | +| :--- | :--- | +| `Content-Type` | `application/x-www-form-urlencoded` | +| `Authorization` | Base64-строка зашифрованного хеша (см. ниже) | +| `key-name` | Ваш **Alias**, полученный от банка | + +### 3.2. Подпись сообщения (Security) +Процесс формирования заголовка `Authorization`: + +1. **Подготовка данных:** Сформируйте JSON-тело запроса. Исключите все пробелы, табуляции и переносы строк между ключами и значениями. +2. **Вычисление хеша и подпись:** + ```bash + # Расчет SHA256 и подпись приватным ключом + openssl dgst -sha256 -sign client.key -out signature.txt block.txt + ``` +3. **Кодирование в Base64:** + ```bash + # Получение строки для заголовка Authorization + base64 signature.txt > signature64.txt + ``` + +--- + +## 4. Тестирование + +### 4.1. Эндпойнт тестовой среды +`https://217.12.103.132:2443/fsCryptoProxy` + +### 4.2. Пример запроса (GetQRCd) +**Body:** +```json +{ + "command":"GetQRCd", + "TermNo":"90080567", + "qrcType":"01", + "amount":"100", + "currency":"RUB", + "paymentPurpose":"Назначение платежа" +} +``` + +> **Важно по полю `paymentPurpose`:** +> * Макс. длина: 140 символов. +> * Допустимы: Латиница, Кириллица (кроме Ё/ё), цифры и спецсимволы. +> * Перенос строки передается как `\\n` (двойной слэш для JSON). + +### 4.3. Как провести тестовую оплату +1. Сгенерируйте QR-код через API. +2. Откройте на смартфоне: [testpay.alfabank.ru/sbp-page](https://testpay.alfabank.ru/sbp-page). +3. Нажмите **"Сканировать QR"** и наведите камеру на код. +4. Нажмите **"Произвести оплату"**. Выбор банка не требуется. + +--- + +## 5. Статусы и уведомления + +### Получение статуса платежа +Существует два способа: +1. **Запрос `GetQRCstatus`:** Опрос шлюза клиентом. +2. **Callback-уведомления:** ПШ банка отправляет POST-запрос на ваш сервер. + +### Настройка Callback +* Сервер ТСП должен быть публичным (HTTPS, порт 443). +* IP-адреса банка для белого списка: `217.12.97.124`, `217.12.101.32`. +* Для включения отправьте URL обработчика на [acquiring@alfabank.ru](mailto:acquiring@alfabank.ru). + +### Лимиты на тестовой среде (`GetQRCstatus`) +* **Лимит ТСП:** не более 4 запросов в минуту. +* **Общий лимит НСПК:** 60 запросов в минуту на весь банк. +* При превышении возвращается ошибка `429 Too Many Requests`. + +--- + +## 6. Переход в промышленную среду (Production) + +Для выхода в "бой" необходимо: +1. Заключить договор по СБП с Альфа-Банком. +2. Сгенерировать новую ключевую пару для промышленной среды. +3. Направить письмо на регистрацию (аналогично тестовой, но с пометкой "промышленный стенд"). +4. Срок предоставления доступов — **до 3 рабочих дней**. + +## Общие положения + +### Техническая документация СБП: Общие положения + +Данный документ описывает принципы взаимодействия, идентификации и основные бизнес-сценарии при работе с Системой Быстрых Платежей (СБП) через хост Альфа-Банка. + +--- + +## 1. Каналы взаимодействия и безопасность + +Взаимодействие осуществляется по протоколу **HTTP(S)** с обязательной двусторонней аутентификацией. + +### Требования к сертификатам +* **Тип:** Клиентские сертификаты RSA/TLS. +* **Управление:** Порядок выпуска и установки определяется Удостоверяющим Центром Заказчика. +* **Именование (Alias):** На прокси-сервере Заказчика должны соблюдаться строгие правила именования: + +| Параметр | Требование к имени (алиасу) | +| :--- | :--- | +| **Обычный запрос** | Должно соответствовать коду терминала и реквизиту заголовка `key-name`. | +| **Проверка соединения** | Должно быть равно параметру `TermNo` в теле запроса и заголовку `key-name`. | + +--- + +## 2. Идентификация Виртуального терминала + +Для работы в системе каждому терминалу присваивается уникальный идентификатор — **TermNo**. + +* **Назначение:** Определение конкретного виртуального терминала, кассы или системы. +* **Привязка:** TermNo определяет принадлежность к Юридическому лицу (ЮЛ), конкретной точке продаж (ТСП) и расчетному счету, на который будут поступать средства. +* **Лимиты:** Минимум 1 терминал на адрес ТСП, максимум — по запросу. +* **Применение:** + * Сохраняется в настройках терминала. + * Используется на прикладном уровне протокола совместно с сертификатом. + * **Обязателен** для генерации динамических QR-кодов и проверки статуса оплаты. + +--- + +## 3. Общий порядок работы + +### 3.1. Оплата покупки (C2B) +Процесс проведения оплаты через динамический QR-код: + +1. **Инициация:** Кассир вводит сумму (валюта и назначение платежа обычно подставляются автоматически). +2. **Запрос QR:** ТСП запрашивает динамический QR-код у Банка. +3. **Отображение:** ТСП выводит QR на экран или печатает пре-чек. +4. **Действия клиента:** + * Сканирует QR через банковское приложение. + * Подтверждает оплату. +5. **Проверка:** ТСП запрашивает подтверждение статуса платежа. +6. **Фискализация:** При получении статуса «Оплачено» ТСП печатает чек. + +**Обязательные реквизиты в чеке оплаты:** +* `qrcId` (Идентификатор QR-кода) +* Код транзакции СБП +* Дата и время операции + +--- + +### 3.2. Возврат покупки +Возврат средств имеет ряд технологических особенностей. + +> [!IMPORTANT] +> **Ограничения возврата:** +> * Возможен только при наличии чека и кода транзакции СБП. +> * Осуществляется только по номеру телефона плательщика. +> * Средства возвращаются только в тот же Банк-участник СБП, с которого была оплата. + +**Параметры для инициации возврата:** +* Сумма (полная или частичная) и валюта. +* Данные из чека: `qrcId`, Код транзакции, Дата оплаты. + +**Процесс подтверждения:** +1. Хост Банка проверяет наличие исходной операции. +2. Кассир проходит аутентификацию (ввод одноразового кода SMS/Push или иная проверка полномочий). +3. ТСП отправляет финальный запрос на возврат. + +**Реквизиты в чеке возврата:** +* Код транзакции `payrrn` +* Сумма возврата + +--- + +## 4. Работа с кассовыми ссылками + +Кассовая ссылка — это многоразовый QR-код, который активируется под конкретную покупку. + +### Жизненный цикл ссылки +1. **Регистрация:** ТСП через Агента регистрирует ссылку в ОПКЦ СБП. QR-код размещается в кассовой зоне. +2. **Активация:** В момент покупки ТСП отправляет запрос на активацию ссылки, передавая `сумму`, `валюту` и `назначение платежа`. + * *Совет:* Для получения уведомлений передавайте адрес `callback-url`. +3. **Оплата:** Клиент считывает статическую ссылку, которая после активации ведет на оплату конкретного счета. +4. **Деактивация:** Если оплата не состоялась, ТСП отправляет запрос на деактивацию. +5. **Изменение счета:** ТСП может изменить расчетный счет, привязанный к ссылке, через запрос к Агенту ТСП (автоматические уведомления об изменении не поддерживаются). + +--- + +## 5. Привязка счета и рекуррентные платежи + +Сценарии для реализации оплат «в один клик» или подписок. + +### Сценарии регистрации привязки +| Тип сценария | Описание | +| :--- | :--- | +| **Чистая привязка** | Регистрация QR-кода типа `03`. Клиент сканирует код только для привязки счета без оплаты. | +| **Оплата + Привязка** | При регистрации обычного QR на оплату передается параметр `subscriptionPurpose`. После оплаты банк предлагает клиенту привязать счет. | + +### Оплата по инициативе ТСП (Списание без участия клиента) +1. ТСП регистрирует QR для оплаты с привязанного счета. +2. ТСП направляет запрос на оплату в НСПК. +3. НСПК запрашивает подтверждение у Банка Плательщика. +4. При положительном ответе инициируется C2B операция, и Агент ТСП получает уведомление о финальном статусе. + +--- + +## Справочник параметров (Сниппеты данных) + +При формировании запросов используйте следующие ключевые поля: + +```json +// Пример ключевых полей для активации кассовой ссылки / оплаты +{ + "TermNo": "12345678", // Номер терминала + "amount": 10000, // Сумма в копейках/единицах + "currency": "RUB", // Валюта + "qrcId": "AD100000...", // ID QR-кода + "payrrn": "3021...", // Код транзакции (для возвратов) + "callbackUrl": "https://..." // Адрес для уведомлений +} +``` + +# Статический QR-код (СБП) + +Статический QR-код — это инструмент безналичной оплаты через Систему быстрых платежей (СБП), являющийся альтернативой эквайрингу. Изображение QR-кода остается неизменным, его можно распечатать и разместить в кассовой зоне. + +### Особенности +* **Варианты реализации:** + * С открытой суммой (вводит покупатель). + * С фиксированной суммой (задает продавец при генерации). +* **Способы оплаты:** Сканирование камерой смартфона или использование NFC-метки. +* **Скорость:** Средства поступают на счет продавца мгновенно. +* **Оборудование:** Терминал не требуется. + +--- + +## 1. Регистрация статического QR-кода + +Метод `GetQRCd` используется для формирования платежной ссылки и получения изображения QR-кода. + +### Параметры запроса +| Параметр | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCd`. | +| `TermNo` | String(20) | Y | Уникальный идентификатор терминала. | +| `qrcType` | String(2) | Y | Тип QR-кода. Для статического — `01`. | +| `amount` | Number | O | Сумма в копейках. Если не указана — сумма открытая. | +| `currency` | String(3) | O | Код валюты (например, `RUB`). | +| `paymentPurpose` | String(140) | O | Назначение платежа. | +| `width` / `height` | String | O | Размеры изображения QR-кода в пикселях. | +| `redirectUrl` | String(1024)| O | Ссылка для возврата клиента в приложение/на сайт ТСП. | +| `messageID` | String(1024)| O | Уникальный ID сообщения (GUID). Только латиница. | +| `queryData.notificationUrl` | String(512) | O | URL для получения уведомления о статусе оплаты. | + +### Пример запроса +```json +{ + "command": "GetQRCd", + "TermNo": "90080567", + "qrcType": "01", + "width": "600", + "height": "600", + "amount": 10000, + "currency": "RUB", + "paymentPurpose": "Оплата заказа №123", + "messageID": "550e8400-e29b-41d4-a716-446655440000", + "queryData": { + "notificationUrl": "https://yourserver.com/sbp/notify" + }, + "redirectUrl": "https://yourshop.ru/success" +} +``` + +### Параметры ответа +| Параметр | Тип данных | Назначение | +| :--- | :--- | :--- | +| `ErrorCode` | String | Код ответа (0 — успех). | +| `image` | String | Изображение QR-кода в формате BASE64. | +| `payload` | String | Платежная ссылка (содержимое QR-кода). | +| `qrcId` | String | Уникальный идентификатор QR-кода. | +| `status` | String | Статус регистрации ссылки (например, `CREATED`). | + +--- + +## 2. Нотификация о статусе оплаты + +После успешной оплаты Банк отправляет POST-запрос на `notificationUrl`, указанный при регистрации. + +### Параметры уведомления +| Параметр | Тип данных | Назначение | +| :--- | :--- | :--- | +| `qrcId` | String | Идентификатор QR-кода. | +| `trxId` | String | Уникальный ID платежа в НСПК. | +| `status` | String | `ACWP` — успех, `RJCT` — отклонено. | +| `amount` | Number | Сумма платежа в копейках. | +| `timestamp` | String | Время операции по Гринвичу (GMT). | +| `payerId` | String | Маскированный номер телефона плательщика. | + +### Пример уведомления +```json +{ + "command": "qrc/notification", + "qrcId": "AS10000NJTDV88TN82CRT8CG1AU690OF", + "trxId": "A31040920067662400000550448AD7B3", + "status": "ACWP", + "amount": 10000, + "timestamp": "2023-04-14T09:20:06.000Z", + "payrrn": "000051992395", + "TermNo": "90080567" +} +``` +*ТСП должно ответить HTTP-кодом `200 OK`.* + +--- + +## 3. Проведение возврата + +Возврат средств выполняется в два этапа. + +### 3.1. Проверка возможности возврата (`GetQRCreversalData`) +Используется для получения данных о плательщике и проверки доступности операции. + +**Запрос:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `qrcId` | Y | ID QR-кода из оригинального платежа. | +| `trxId` | Y | ID транзакции НСПК. | +| `amount` | O | Сумма возврата. Если пусто — полный возврат. | + +**Пример ответа:** +```json +{ + "ErrorCode": 0, + "payerBnkName": "Альфа-Банк", + "payerId": "*1779", + "trxDT": "20230414062006", + "message": "OK" +} +``` + +### 3.2. Выполнение возврата (`QRCreversal`) +Непосредственная инициация перевода средств клиенту. + +**Запрос:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `messageID` | Y | GUID, полученный в ответе `GetQRCreversalData`. | +| `queryData.notificationUrl` | O | URL для уведомления о статусе возврата. | + +--- + +## 4. Запрос статуса возврата + +Метод `GetQRCreversalStatus` используется для уточнения финального статуса операции возврата (B2C). + +### Параметры запроса +Для поиска операции необходимо передать одну из пар: +1. `payrrn` ИЛИ `originalTrxId` (для поиска исходного платежа). +2. `trxId` ИЛИ `messageID` (для идентификации самого возврата). + +### Статусы возврата в ответе +* `ACWP` — Возврат успешно завершен. +* `RJCT` — Операция отклонена. +* `NTST` — Статус неизвестен (в обработке). + +### Пример ответа +```json +{ + "ErrorCode": 0, + "amount": 10000, + "status": "ACWP", + "originalTrxId": "A31040920067662400000550448AD7B3", + "trxId": "B31071502287201D00001650448AD7B3" +} +``` + +--- +*Примечание: Все текстовые данные в запросах должны передаваться в кодировке UTF-8, формат передачи данных — JSON.* + +# Интеграция динамических QR-кодов (СБП) + +Оплата по динамическому QR-коду — это способ безналичной оплаты через Систему Быстрых Платежей (СБП). QR-код создается отдельно под каждую покупку, содержит сумму и реквизиты. Средства мгновенно поступают на счёт продавца. + +## 1. Регистрация динамического QR-кода +**Метод:** `GetQRCd` + +Используется для генерации QR-кода под конкретный заказ. + +### Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCd` | +| `TermNo` | String(20) | Y | Уникальный идентификатор терминала | +| `qrcType` | String(2) | Y | Тип QR-кода. Для динамического — `02` | +| `amount` | Number | Y | Сумма в минорных единицах (копейках) | +| `currency` | String(3) | Y | Код валюты (для рублей — `RUB`) | +| `OrderNumber` | String(1000)| O | Номер заказа (только латиница и цифры) | +| `paymentPurpose`| String(140) | O | Назначение платежа | +| `qrTtl` | String(6) | O | Срок жизни ссылки в минутах (мин. 1, рек. от 5) | +| `queryData.notificationUrl` | String(512) | O | URL для уведомления о статусе оплаты | +| `redirectUrl` | String(1024)| O | Ссылка для возврата клиента в приложение/сайт | +| `extJsonParams` | Object | O | Блок дополнительных параметров (JsonParam1-10) | + +**Для подписок (рекуррентных платежей):** +* `subscriptionServiceId`: Идентификатор привязки. +* `subscriptionServiceName`: Наименование привязки. + +### Пример запроса +```json +{ + "command": "GetQRCd", + "TermNo": "90080567", + "amount": "10000", + "currency": "RUB", + "qrcType": "02", + "qrTtl": "5", + "OrderNumber": "FYI123456", + "queryData": { + "notificationUrl": "https://sbp-payments.your-site.com/callback" + } +} +``` + +### Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String | Y | Код ответа (0 — успех) | +| `image` | String | Y | Изображение QR-кода в формате Base64 | +| `payload` | String | Y | Платежная ссылка СБП | +| `qrcId` | String | Y | Уникальный идентификатор QR-кода | +| `status` | String | Y | Статус регистрации (например, `CREATED`) | + +--- + +## 2. Запрос статуса оплаты +**Метод:** `GetQRCstatus` + +Направляется кассой/терминалом для проверки факта оплаты. +> **Важно:** Запрос следует направлять не ранее, чем через 10 секунд после формирования QR, и не чаще чем раз в 3 секунды. + +### Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCstatus` | +| `TermNo` | String | Y | Идентификатор терминала | +| `qrcId` | String | Y/O | ID QR-кода (обязательно, если нет payrrn) | +| `payrrn` | String | Y/O | Референс запроса в системе Банка | + +### Возможные статусы (`status`) +1. `ACWP` (ACCEPTED) — Операция завершена успешно. +2. `RJCT` (REJECTED) — Операция отклонена. +3. `NTST` (NOT_STARTED) — Операция не найдена (нужен повтор запроса). +4. `RCVD` (RECEIVED) — Операция в обработке. + +### Пример ответа (Успех) +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + "trxId": "A3013090427361010000057B3DA2D4A7", + "amount": 10000, + "payerId": "*********1234" +} +``` + +--- + +## 3. Нотификация о финальном статусе +**Метод:** `qrc/notification` + +Запрос отправляется со стороны Банка на `notificationUrl` ТСП. + +### Формат уведомления +```json +{ + "command": "qrc/notification", + "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + "status": "ACWP", + "amount": "10000", + "trxId": "A3013090427361010000057B3DA2D4A7", + "timestamp": "2022-10-27T14:33:49.000Z" +} +``` +*ТСП должно ответить HTTP-кодом `200`.* + +--- + +## 4. Проведение возврата +Возврат может быть выполнен в два этапа (проверка + выполнение) или в один этап (при передаче `messageID`). + +### 4.1 Проверка возможности возврата (`GetQRCreversalData`) +Используется для получения данных о плательщике и проверки доступного остатка. + +### 4.2 Выполнение возврата (`QRCreversal`) +**Параметры запроса:** +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `QRCreversal` | +| `amount` | Number | O | Сумма возврата (если не указана — полный возврат) | +| `qrcId`/`trxId` | String | Y | Идентификаторы оригинальной операции | +| `ReturnRestAmount`| Boolean| O | Вернуть остаток доступных средств в ответе | + +### Пример ответа на возврат +```json +{ + "ErrorCode": 0, + "message": "Возврат проведен", + "amount": 10000, + "trxId": "A3024113609260070000086B8426B817", + "restAmount": "99.87" +} +``` + +--- + +## 5. История и статусы возвратов + +### Запрос истории (`GetQRCreversalHistory`) +Позволяет получить список всех попыток возврата по одной транзакции оплаты. + +**Пример структуры массива `refunds` в ответе:** +```json +"refunds": [ + { + "status": "ACWP", + "amount": 10000, + "trxId": "B51390823097450W0000180011510503", + "trxDT": "20250519082345" + }, + { + "status": "RJCT", + "amount": 10000, + "trxId": "A4327120041167130000020011381101" + } +] +``` + +--- + +## 6. Нотификация о возврате +**Метод:** `b2c-refund/notification` + +Банк уведомляет систему ТСП о финальном статусе операции возврата. + +### Пример уведомления +```json +{ + "command": "b2c-refund/notification", + "status": "ACWP", + "amount": "10000", + "originalTrxId": "X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + "trxId": "A3024113609260070000086B8426B817" +} +``` + +--- + +## Примечания +* **Формат данных:** Все текстовые данные в ответах передаются в формате `urlencoded`. +* **Суммы:** Все суммы в запросах передаются как целые числа в копейках. +* **Ошибки:** Список кодов ошибок приведен в Приложении №2 (согласно основной документации Банка). +* **Успешная оплата:** Считается подтвержденной только при получении статуса `ACWP` и наличии `trxId`. + +# Кассовая платёжная ссылка СБП: Техническая документация + +**Кассовая платёжная ссылка** — это гибридное решение, объединяющее преимущества статического и динамического QR-кодов. QR-код остается неизменным (его можно распечатать один раз), но сумма оплаты передается с кассы в момент покупки, что исключает ошибки ручного ввода со стороны клиента. + +## Общие положения +* Для каждой кассы/терминала создается уникальная ссылка. +* Сумма передается в **минорных единицах** (копейках). +* Текстовые данные в ответах передаются в формате `urlencoded`. + +--- + +## 1. Регистрация кассовой платёжной ссылки +Метод `RegCashQRc` используется для генерации постоянного QR-кода для терминала. + +### Параметры запроса +| Параметр | Тип | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `RegCashQRc` | +| `TermNo` | String | Y | Уникальный ID терминала (до 20 симв.) | +| `mediaType` | String | N | Тип картинки (напр., `image/png`) | +| `width` | String | N | Ширина изображения | +| `height` | String | N | Высота изображения | +| `redirectUrl` | String | N | Ссылка для возврата клиента в приложение ТСП | +| `qrcId` | String | N | ID для привязки предвыпущенных NFC-табличек | + +**Пример запроса:** +```json +{ + "command": "RegCashQRc", + "TermNo": "90080567", + "mediaType": "image/png", + "width": "600", + "height": "600", + "redirectUrl": "https://exampletsp.io/callback" +} +``` + +--- + +## 2. Активация ссылки (Передача суммы) +Метод `ActivateCashQRc` вызывается кассой в момент совершения покупки для установки суммы и параметров платежа. + +### Параметры запроса +| Параметр | Тип | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `ActivateCashQRc` | +| `TermNo` | String | Y | ID терминала | +| `qrcId` | String | Y | ID QR-кода | +| `amount` | Number | Y | Сумма в копейках | +| `currency` | String | N | Валюта (по умолчанию `RUB`) | +| `qrTtl` | String | N | Срок жизни активации (5–20 мин) | +| `queryData.notificationUrl` | String | N | URL для уведомления об оплате | + +**Пример запроса:** +```json +{ + "command": "ActivateCashQRc", + "TermNo": "90080567", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + "amount": 10000, + "currency": "RUB", + "qrTtl": "5", + "queryData": { + "notificationUrl": "https://sbp-payments.your-site.ru" + } +} +``` + +--- + +## 3. Проверка статуса оплаты +Метод `GetQRCstatus` используется для получения финального статуса транзакции. Рекомендуется запрашивать не ранее 10 сек. после активации и не чаще раза в 3 сек. + +### Статусы оплаты (поле `status`) +* **ACWP** (ACCEPTED) — Оплата успешно завершена. +* **RJCT** (REJECTED) — Операция отклонена. +* **NTST** (NOT_STARTED) — Оплата еще не инициирована. +* **RCVD** (RECEIVED) — В обработке. + +**Пример ответа (Успех):** +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "trxId": "A30180803159571F0000097B3DA2D4A7", + "amount": 10000, + "payerId": "*********1234", + "payrrn": "000056251465" +} +``` + +--- + +## 4. Деактивация ссылки +Метод `DelCashQRc` используется для досрочной отмены ожидания оплаты (например, если клиент отказался от покупки). + +**Пример запроса:** +```json +{ + "command": "DelCashQRc", + "TermNo": "90080567", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" +} +``` + +--- + +## 5. Возврат платежа +Возврат по СБП выполняется в два этапа (или в один при наличии `messageID`). + +### Этап 1: Проверка возможности возврата (`GetQRCreversalData`) +Позволяет узнать доступный остаток и получить данные для проведения возврата. + +### Этап 2: Проведение возврата (`QRCreversal`) +**Пример запроса на возврат:** +```json +{ + "command": "QRCreversal", + "TermNo": "90080567", + "payrrn": "000056251465", + "amount": 10000, + "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8" +} +``` + +--- + +## 6. Нотификации (Webhooks) +Банк отправляет POST-запросы на ваш `notificationUrl` при изменении статуса оплаты или возврата. + +### Уведомление об оплате (`qrc/notification`) +```json +{ + "command": "qrc/notification", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + "status": "ACWP", + "amount": 10000, + "trxId": "A30180803159571F0000097B3DA2D4A7" +} +``` + +--- + +## 7. Изменение параметров ссылки +Метод `ChangeAccForCashQRc` позволяет перепривязать QR-код к другому счету, терминалу или изменить `redirectUrl`. + +| Параметр | Назначение | +| :--- | :--- | +| `NewTermNo` | Перенос на новый ID терминала | +| `NewMerchantId` | Перенос на другую торговую точку | +| `account` | Смена расчетного счета | + +--- + +## Приложение: Коды ошибок (ErrorCode) +| Код | Описание | +| :--- | :--- | +| `0` | Успешно | +| `3` | Не передан обязательный параметр | +| `16` | Некорректный TermNo | +| `41` | Некорректный qrcId | +| `301` | Превышен временной диапазон поиска | +| `RQ05019` | Не передан параметр amount при активации | + +> **Примечание:** При получении статуса `NTST` необходимо продолжать опрос статуса до получения финального результата (`ACWP` или `RJCT`). + +# Привязка счёта и подписки СБП: Техническая документация + +Данный функционал позволяет ТСП (Торгово-сервисным предприятиям) выполнять привязку банковского счёта клиента для проведения последующих платежей без участия плательщика (рекуррентные платежи, оплата в один клик). + +--- + +## 1. Привязка счёта без оплаты +Используется для регистрации QR-кода, целью которого является только установление связки между счётом клиента и ТСП. + +### 1.1. Метод `RegQRcSub` + +**Параметры запроса:** + +| Параметр | Тип | Обяз. | Описание | +| :--- | :--- | :---: | :--- | +| `command` | String | Да | Тип запроса. Константа: `RegQRcSub`. | +| `TermNo` | String | Да | Уникальный идентификатор терминала. | +| `qrcType` | String | Да | Тип QR-кода. Константа: `03`. | +| `subscriptionPurpose` | String | Да | Цель привязки. Отображается клиенту в приложении банка. | +| `queryData.notificationUrl` | String | Да | URL для получения уведомления о результате привязки. | +| `qrTtl` | String | Нет | Срок жизни ссылки в минутах (1 — 129 600). По умолчанию: 4320 (3 суток). | +| `redirectUrl` | String | Нет | Ссылка для возврата клиента в приложение/на сайт ТСП. | +| `subscriptionServiceId` | String(32) | Нет | Идентификатор сервиса подписки (используется с `subscriptionServiceName`). | +| `subscriptionServiceName`| String(70) | Нет | Наименование сервиса подписки. | + +**Пример запроса:** +```json +{ + "command": "RegQRcSub", + "TermNo": "90080567", + "qrTtl": "10", + "qrcType": "03", + "subscriptionPurpose": "Подписка на оплату услуг Интернет 500р./мес.", + "queryData": { + "notificationUrl": "https://sbp-subscription.example.com" + }, + "redirectUrl": "https://exampletsp.io/callback" +} +``` + +**Параметры ответа:** + +| Параметр | Описание | +| :--- | :--- | +| `ErrorCode` | Код ответа (0 или RQ00000 — успех). | +| `qrcId` | Идентификатор QR-кода. | +| `payload` | Платежная ссылка для формирования QR или перехода. | +| `payrrn` | Референс запроса в системе Банка. | + +--- + +### 1.2. Нотификация о результате привязки (`subscription/notification`) +Банк отправляет POST-запрос на `notificationUrl` ТСП. + +**Параметры нотификации:** +* `status`: `ACWP` (оформлено) или `RJCT` (отказ). +* `subscriptionToken`: Уникальный токен привязки (необходим для будущих оплат). +* `memberId`: Идентификатор банка плательщика. + +> **Важно:** Значения `subscriptionToken` и `memberId` необходимо сохранить. Без них проведение платежей по инициативе ТСП невозможно. + +--- + +## 2. Оплата с последующей привязкой счёта +Позволяет клиенту совершить первую покупку и одновременно разрешить ТСП списывать средства в будущем. + +### 2.1. Метод `GetQRCd` (Тип 02) + +Для этого сценария используется стандартный метод генерации QR, но с обязательным заполнением поля `subscriptionPurpose`. + +**Ключевые параметры:** +* `qrcType`: `02` (динамический QR). +* `amount`: Сумма первого платежа в копейках. +* `subscriptionPurpose`: Описание подписки (наличие этого поля активирует сценарий привязки). +* `queryData.notificationUrl_sub`: (Опционально) Отдельный URL для уведомления именно о привязке. + +**Логика уведомлений:** +1. При успешной операции ТСП получает **два** callback-уведомления: + - О статусе платежа (`qrc/notification`). + - О статусе привязки (`subscription/notification`). +2. Если платеж прошел, но клиент отказался от привязки — придет уведомление об успехе оплаты и уведомление об отказе в подписке. + +--- + +## 3. Оплата с привязанного счёта (по инициативе ТСП) +Сценарий "бесшовной" оплаты без участия клиента. Проводится в два этапа. + +### Этап 1: Генерация ссылки через `GetQRCd` +Создается технический QR-код (тип `02`), к которому будет "привязан" платеж. +* `paymentPurpose`: Обязательно для заполнения. +* `amount`: Сумма списания. + +### Этап 2: Запрос на списание `QRCSubPayPetition` +ТСП отправляет команду банку на исполнение платежа, используя полученный ранее токен. + +**Параметры запроса:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `command` | Да | `QRCSubPayPetition` | +| `subscriptionToken` | Да | Токен, полученный при регистрации привязки. | +| `SenderMemberId` | Да | Идентификатор банка плательщика (`memberId`). | +| `qrcId` | Да | ID QR-кода, созданного на Этапе 1. | + +**Пример запроса:** +```json +{ + "command": "QRCSubPayPetition", + "TermNo": "90080567", + "subscriptionToken": "70LSS7DN18SJQRS10006DNPKLJL24B05", + "SenderMemberId": "100000000008", + "qrcId": "AD10000BBJKO23GB98LA1FGBRIHH3K89" +} +``` + +### 3.1. Статусы решения банка (`resolution/notification`) +После запроса на списание банк присылает уведомление с результатом: + +| Код | Описание | +| :--- | :--- | +| `RQ00030` | **Успех.** Согласие на проведение платежа. | +| `RQ05031` | Отказ: Привязка не найдена (клиент мог её удалить). | +| `RQ05060` | Отказ: Недостаточно средств. | +| `RQ05061` | Отказ: Превышен лимит СБП. | +| `RQ05063` | Отказ: Подозрение на мошенничество. | + +--- + +## 4. Запрос статуса привязки +Если ТСП не получило callback, можно запросить статус привязки вручную. + +### Метод `GetQRCSubStatus` + +**Запрос:** +```json +{ + "command": "GetQRCSubStatus", + "TermNo": "90080567", + "qrcId": "BB1S002PRSK6SR3E9R7P0H077UKN1QVF" +} +``` + +**Ответ (успешная привязка):** +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "subscriptionToken": "70LSS7DN18SJQRS10006DNPKLJLAGT77", + "memberId": "600000000015", + "message": "OK" +} +``` + +--- + +## Важные примечания для разработчиков + +1. **Лимиты:** Оплата с привязанного счета возможна на сумму до **1 000 000 руб.** за одну операцию. +2. **Кодировка:** Текстовые данные в ответах могут передаваться в формате `urlencoded` (например, `%u0423%u0441%u043F%u0435%u0445` для слова "Успех"). +3. **Безопасность:** Система ТСП должна игнорировать неизвестные дополнительные параметры в уведомлениях от НСПК/Банка, не считая их ошибкой. +4. **Хранение данных:** Потеря `subscriptionToken` делает невозможным рекуррентное списание. В этом случае потребуется повторная привязка через QR-код. + +# Цифровой рубль: Техническая документация по интеграции + +Цифровой рубль (ЦР) — это третья форма национальной валюты, дополняющая наличные и безналичные средства. Счета цифрового рубля открываются на платформе Центрального банка, а доступ к ним осуществляется через мобильные приложения и интернет-банки коммерческих банков. + +Прием платежей в ЦР осуществляется в рамках **Универсального платёжного кода (УПК)**. + +--- + +## 1. Динамический QR-код (Одноразовый УПК) + +Динамический код формируется под конкретную операцию с фиксированной суммой. + +### 1.1. Регистрация динамического УПК +Для генерации кода можно использовать существующий метод `GetQRCd` или специализированный метод `ReqUniQr`. + +#### Метод `ReqUniQr` +Запрос направляется ТСП в Банк для регистрации универсальной платёжной ссылки в API СБП. + +**Параметры запроса:** + +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `ReqUniQr` | +| `TermNo` | String | Y | Уникальный идентификатор терминала | +| `amount` | Number | O* | Сумма в копейках (обязательна для `uniQrType = 02`) | +| `uniQrType` | String | Y | Тип ссылки: `01` — многоразовая, `02` — одноразовая | +| `mediaType` | String | O | Расширение QR-кода (напр., `image/png`) | +| `width` / `height` | String | O | Размеры изображения в пикселях | +| `paymentPurpose` | String | O | Назначение платежа | +| `redirectUrl` | String | O | URL для возврата в приложение ТСП (ASCII/RFC3986) | +| `messageID` | String | O | Уникальный GUID сообщения | +| `qrTtl` | String | O | Срок жизни ссылки в минутах | +| `queryData.notificationUrl` | String | O | URL для уведомления о статусе оплаты | + +**Пример запроса:** +```json +{ + "command": "ReqUniQr", + "TermNo": "90080567", + "amount": "10000", + "uniQrType": "02", + "redirectUrl": "https://alfabank.ru/sme/payservice/sbp/", + "mediaType": "image/png", + "width": "600", + "height": "600", + "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8", + "queryData": { + "notificationUrl": "https://sbp-payments", + "SenderFIO": "Иванов Иван Иванович" + } +} +``` + +**Параметры ответа:** +- `ErrorCode`: `0` — успех. +- `payload`: Платёжная ссылка. +- `image`: Изображение QR-кода в Base64. +- `uniQrId`: Идентификатор ссылки. +- `status`: Статус (обычно `CREATED`). + +--- + +### 1.2. Проверка статуса оплаты динамического УПК +Используется метод `GetUniQrStatus`. + +**Специфические статусы для Цифрового рубля:** +* `ENDD`: Платёж в ЦР обработан, но финальный результат (успех/отказ) пока неизвестен. +* `ACDR`: Платёж в ЦР успешно выполнен (аналог `ACWP` для СБП). + +**Структура блока `data` (массив Record) в ответе:** + +| Ключ | Описание | +| :--- | :--- | +| `paymentServiceId` | `PS0000000001` (СБП) или `PS0000000002` (ЦР) | +| `status` | `NTST` (не начат), `RCVD` (в процессе), `ACWP` (успех СБП), `RJCT` (отказ), `ENDD` (ЦР в обработке), `ACDR` (успех ЦР) | + +--- + +## 2. Кассовая платёжная ссылка (Многоразовый УПК) + +Многоразовый код, который обычно размещается в кассовой зоне. + +### 2.1. Регистрация кассового УПК +Метод: `RegCashUniQr`. + +**Особенности:** +* Позволяет привязать конкретный `qrcId`. +* В настройках ТСП на стороне Банка должен быть обязательно указан счет ЦР (`accountDR`). + +**Пример ответа:** +```json +{ + "ErrorCode": "0", + "message": "OK", + "TermNo": "90080567", + "payload": "https://qr.nspk.ru/BS2R003FS8EFGAVM852PQS13N894HDLU?type=01...", + "image": "iVBORw0KGgoAAAANSUhEUgAAAlg...", + "qrcId": "BS2R003FS8EFGAVM852PQS13N894HDLU", + "status": "CREATED" +} +``` + +--- + +### 2.2. Изменение параметров кассового УПК +Метод `ChangeAccForCashUniQr` позволяет обновить привязанные счета или параметры терминала без смены самого QR-кода. + +**Ключевые параметры для изменения:** +* `account`: Новый счет для СБП. +* `accountDR`: Новый счет для Цифрового рубля (строго 55 символов). +* `NewTermNo`: Смена ID терминала. +* `NewMerchantId`: Смена ID мерчанта в НСПК. + +--- + +### 2.3. Проверка статуса кассового УПК +Метод: `GetCashUniQrStatus`. + +**Важные поля ответа:** +* `paymentServiceId`: Определяет, как заплатил клиент (`PS0000000002` — Цифровой рубль). +* `cashRegisterQrcStatus`: Статус самой ссылки (`WAITING_PAYMENT`, `IN_PROGRESS`, `DEACTIVATED`). + +--- + +## 3. Нотификация об исполнении перевода (C2B) + +Сообщение отправляется со стороны Банка на сервер ТСП при получении финального статуса платежа. + +**Метод:** `paymentDR/notification` (POST запрос) + +**Параметры запроса:** + +| Код ключа | Тип данных | Назначение | +| :--- | :--- | :--- | +| `command` | String | `paymentDR/notification` | +| `uniQrId` | String | Идентификатор платежа | +| `operationId` | String | ID операции на платформе ЦР | +| `status` | String | Статус (напр. `ACWP` или `RCVD`) | +| `amount` | String | Сумма в рублях (с разделителем-точкой) | +| `timestamp` | ISO8601 | Дата и время операции | +| `payrrn` | String | Референс платежа | + +**Пример нотификации:** +```json +{ + "command": "paymentDR/notification", + "uniQrId": "AD2000670LSS7DN18SJQDNP4B05KLJL1", + "operationId": "546464AX45546", + "status": "ACWP", + "amount": "10241.21", + "timestamp": "2024-08-01T10:15:00.000Z", + "payrrn": "102345678912", + "TermNo": "90080567", + "merchantName": "Рога и Копыта", + "purpose": "Кофе и булочка" +} +``` + +**Ожидаемый ответ от ТСП:** +* `HTTP 200 OK` — уведомление успешно принято. +* `HTTP 500` — внутренняя ошибка (будет произведена повторная попытка). + +--- + +## Приложение: Справочник статусов (status) + +| Код | Описание | Применимость | +| :--- | :--- | :--- | +| **NTST** | Платёж не начат | СБП / ЦР | +| **RCVD** | Платёж инициирован / в обработке | СБП / ЦР | +| **ACWP** | Платёж успешно выполнен | СБП | +| **RJCT** | Платёж отклонён | СБП | +| **ENDD** | Платёж обработан (результат уточняется) | **ЦР** | +| **ACDR** | Платёж успешно выполнен | **ЦР** | + +# Дополнительные методы API СБП (Альфа-Банк) + +Данный документ содержит описание дополнительных методов API для работы с Системой Быстрых Платежей (СБП) через платежный шлюз (ПШ) Альфа-Банка. + +> **Примечание:** Таблицы кодов ответов (`ErrorCode`) и их расшифровок приведены в Приложении №2 к основной документации. + +--- + +## 1. Запрос списка банков-участников СБП (`GetBankList`) + +Метод используется ТСП для получения актуального списка банков, поддерживающих оплату через СБП. + +### 1.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `GetBankList` | +| `messageID` | String (ans-1..1024) | N | Уникальный идентификатор сообщения (GUID) | +| `BankMemberIdFilter` | String (n-11) | N | Фильтр по ID участника СБП (если нужен только один банк) | + +**Пример запроса:** +```json +{ + "command": "GetBankList" +} +``` + +### 1.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | +| `BankList` | Array | N | Коллекция банков-участников | +| `BankList.BankName` | String (an-50) | N | Наименование банка | +| `BankList.BankID` | String (an-12) | N | Идентификатор участника СБП в НСПК | +| `BankList.BankBIK` | String (n-9) | N | БИК банка (если передан из НСПК) | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "message": "Запрос обработан успешно", + "BankList": [ + { + "BankName": "Наименование банка 1", + "BankID": "10000001100", + "BankBIK": "044525823" + }, + { + "BankName": "Наименование банка N", + "BankID": "10000001145", + "BankBIK": "044525829" + } + ] +} +``` + +--- + +## 2. Блокирование QR-кода (`BlockQRcId`) + +Запрос направляется для блокировки ранее сгенерированного QR-кода любого типа. + +### 2.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `BlockQRcId` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | +| `reason` | String (ans-1024) | N | Причина блокировки | + +**Пример запроса:** +```json +{ + "command": "BlockQRcId", + "TermNo": "90080567", + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV", + "reason": "Заказ 12345 направлен в стоп-лист" +} +``` + +### 2.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | + +**Пример успешного ответа (200 OK):** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK" +} +``` + +--- + +## 3. Разблокирование QR-кода (`UnblockQRcId`) + +Запрос используется для восстановления активности ранее заблокированного QR-кода. + +### 3.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `UnblockQRcId` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | + +**Пример запроса:** +```json +{ + "command": "UnblockQRcId", + "TermNo": "90080567", + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV" +} +``` + +### 3.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK" +} +``` + +--- + +## 4. Список заблокированных QR-кодов (`GetBlockedQRcIdList`) + +Запрос позволяет получить перечень всех заблокированных QR-кодов по конкретному терминалу или кассе. + +### 4.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `GetBlockedQRcIdList` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | + +**Пример запроса:** +```json +{ + "command": "GetBlockedQRcIdList", + "TermNo": "90080567" +} +``` + +### 4.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `QRcIdList` | Collection | N | Список заблокированных QR-кодов | +| `QRcIdList.qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | +| `QRcIdList.reason` | String (ans-1024) | N | Причина блокировки | +| `QRcIdList.date` | String (an-20) | **Y** | Дата и время блокировки | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK", + "QRcIdList": [ + { + "date": "2024-04-18 17:17:45", + "qrcId": "BD100000K5II0G369JHR3KBA6SM3FD3V", + "reason": "Заказ 12345 направлен в стоп-лист" + }, + { + "date": "2024-05-01 19:07:15", + "qrcId": "BD100002JN871TSC9SJB7HPVRFD3HQ8T", + "reason": "Заказ 96780 направлен в стоп-лист" + } + ] +} +``` + +--- + +## Обработка ошибок (Общий формат) + +В случае ошибки (например, `400 Bad Request`), шлюз возвращает JSON следующего вида: + +```json +{ + "ErrorCode": "Код ошибки", + "message": "Расшифровка причины ошибки" +} +``` + +# Приложения к технической спецификации СБП + +## Приложение 1. Формат Payload + +В Системе быстрых платежей (СБП) используется формат двухмерного кода **QR Code (ISO/IEC 18004-2015)**. Payload (полезная нагрузка) может быть представлен в двух вариантах. + +### Варианты Payload +* **Короткий вариант:** `https://{HOST}/{QR_ID}` +* **Длинный вариант:** `https://{HOST}/{QR_ID}?type={QR_TYPE}&bank={MEMBER_ID}&sum={SUM}&cur={CUR}&crc={CRC}` + +### Описание параметров URL-based payload + +| Параметр | Описание | Обяз. | Формат | +| :--- | :--- | :---: | :--- | +| **HOST** | `qr.nspk.ru` — для QR_TYPE 01 и 02
`sub.nspk.ru` — для QR_TYPE 03 | y | String | +| **QR_ID** | Идентификатор зарегистрированного QR-кода в СБП | y | String (32 симв.) | +| **QR_TYPE** | Тип QR-кода:
01 — QR Static (наклейка)
02 — QR Dynamic (на кассе)
03 — QR-Subscription (привязка счета) | y | String (2 цифры) | +| **MEMBER_ID** | Идентификатор Банка Получателя (ТСП) | y | String (12 симв.) | +| **SUM** | Сумма в копейках. Обязательна для типа 02. Отсутствует для типа 03. | y/o | String (до 12 цифр) | +| **CUR** | Валюта операции (обязательна, если присутствует SUM) | y/o | String (3 симв.) | +| **CRC** | Значение контрольной суммы | y | String (4 симв.) | + +--- + +## Приложение 2. Описание кодов ответа + +Полный перечень кодов представлен на сайте НСПК. Коды, не описанные ниже, следует обрабатывать как **техническую (системную) ошибку**. + +### Общие коды ошибок системы + +| Код | Сообщение / Описание | +| :--- | :--- | +| **0** | **OK** (Успешно) | +| **-999** | Прочее сообщение FSCryptoProxy | +| **-71** | Неверные данные Basic-авторизации запроса | +| **-9** | Система перегружена. Повторите запрос позже | +| **-7** | Неверная подпись сообщения (ошибка ключей) | +| **-6** | Не передана подпись в заголовке Authorization | +| **-1** | Возникли проблемы при обработке запроса | +| **1** | Внутренняя ошибка | +| **2** | Терминал не обнаружен | +| **8** | Таймаут ответа | +| **25** | Терминал заблокирован | +| **1001** | Сервис временно недоступен | + +### Коды ОПКЦ СБП (RQ-серия) + +| Код | Описание | +| :--- | :--- | +| **RQ00000** | Запрос обработан успешно | +| **RQ03001** | Ошибка валидации. Неверный формат запроса | +| **RQ05002** | Участник (memberId) не найден в СБП | +| **RQ05005** | ТСП (merchantId) не зарегистрировано в СБП | +| **RQ05009** | Сумма (amount) меньше минимально допустимой | +| **RQ05010** | Сумма (amount) больше максимально допустимой | +| **RQ05014** | Идентификатор qrcId не найден | +| **RQ05032** | Отказ Банка Плательщика в выполнении платежа | +| **RQ05040** | Сумма возврата превышает сумму исходной операции | +| **RQ07999** | Техническая ошибка | + +--- + +### Ошибки по конкретным методам + +#### Метод `GetQRCd` (Запрос QR-кода) +| Код | Описание | +| :--- | :--- | +| **3** | Не заполнены данные запроса | +| **28** | Запрос QR-кода не удался, не получен QR_ID | +| **301** | Некорректно заполнены данные | +| **999*** | Неизвестная ошибка. Требуется уточнение статуса | + +#### Метод `GetQRCstatus` (Статус платежа) +| Код | Описание | +| :--- | :--- | +| **4** | Не передан qrcId или payrrn | +| **5** | Не получены данные от СБП | +| **18** | Платеж не найден в запросах B07, B23 | + +#### Методы возврата (`GetQRCreversalData`, `QRCreversal`) +| Код | Описание | +| :--- | :--- | +| **12** | Не найдены данные для возврата | +| **20** | Получен отказ на запрос возврата | +| **22** | Несоответствие payrrn и qrcId в запросе | +| **27** | Возврат невозможен: счет зачисления не равен счету списания | +| **121** | Операция оплаты еще не имеет финального статуса | +| **201** | Отказ: Недостаточно средств на счете для возврата | + +--- + +### Коды callback-уведомлений (Оплата с привязанного счета) + +Используются в методе `resolution/notification`. + +| Код | Описание | +| :--- | :--- | +| **RQ05060** | Недостаточно денежных средств | +| **RQ05061** | Превышен лимит по сумме операций СБП | +| **RQ05063** | Подозрение в мошенничестве (Anti-fraud) | +| **RQ05065** | Счет заблокирован | +| **RQ05067** | Запрещено по требованию законодательства | + +> **Примечание:** Использование кода `RQ05032` допускается не более чем в 20% случаев от общего числа отказов Банка Плательщика. + +--- + +## Приложение 3. Пояснение для колонки «Required» + +| Метка | Значение | +| :---: | :--- | +| **y** | **Yes** — обязательное поле | +| **o** | **Optional** — опциональное поле | +| **y/o** | **Conditional** — условно обязательное (зависит от условий запроса) | + +--- + +## Приложение 4. Типы данных + +| Нотация | Описание | +| :--- | :--- | +| **a** | Символы латинского (A-Z, a-z) и русского (А-Я, а-я) алфавитов. | +| **n** | Цифры 0-9. | +| **an** | Буквенно-цифровой формат (смесь **a** и **n**). | +| **ans** | Буквенно-цифровой формат со спецсимволами (пробел, пунктуация, знаки `№`, `%` и т.д.). | + +**Кодировка:** Все данные передаются в кодировке **UTF-8**. diff --git a/_docs/alfabank/qr_payout/1_main.md b/_docs/alfabank/qr_payout/1_main.md new file mode 100644 index 0000000..bd2852c --- /dev/null +++ b/_docs/alfabank/qr_payout/1_main.md @@ -0,0 +1,430 @@ +Главная + +Добро пожаловать на портал с инструкцией по интеграции СБП C2B + +Здесь есть вся необходимая информация, которая поможет успешно провести прямую интеграцию с платёжным шлюзом Альфа-Ба + +Важное объявление +С 1.11.2024 адрес тестового стенда будет изменён на новый URL — https://217.12.103.132:2443/fsCryptoProxy +Старые адреса http://217.12.103.147:9914/fsCryptoProxy и https://217.12.103.147:443/fsCryptoProxy станут недоступны +В случае если ваши запросы перестанут успешно отрабатываться ПШ банка до 1.11.2024, необходимо заменить URL на новый, не д +Для направления запросов на новый URL обязательно устанавливается MTLS соединение +В случае если у вас нет ключевой пары для поднятия MTLS соединения на тестовой среде, вам необходимо обратиться в банк по  +Информация о том, как направлять запросы с установлением MTLS соединения на тестовой среде, находится по ссылке в разделе + +Обзор API + +• API позволяет направлять запросы на платёжный шлюз Альфа-Банка (далее — ПШ), чтобы совершать операции с помощью сервис + +• Взаимодействие с платёжным шлюзом Альфа-Банка происходит по протоколу HTTPS + +• API использует REST-архитектуру, методы POST + +• POST-запросы используют JSON-аргументы + +• API всегда возвращает ответ в формате JSON + +• Ответ от платежного шлюза всегда содержит код ответа — ErrorCode + +• Если в процессе обработки запроса произойдёт логическая ошибка, API вернёт её описание в поле message + +• Текстовые данные возвращаются в ответе на запрос в формате urlencoded + +• Все вопросы по процессу имплементации через данный протокол API можно направлять на адрес сопровождения — acquiring@alfa + +Процесс аутентификации + +Аутентификация на тестовой среде + +Взаимодействие с платёжным шлюзом Альфа-Банка (далее — ПШ) на тестовой среде происходит через интернет по протоколу HTTP + +Чтобы установить MTLS-соединение на тестовой среде, банк выдаёт клиенту ключевую пару RSA/TLS: сертификат и приватный клю + +MTLS-соединение позволяет произвести двустороннюю аутентификацию. + +Внимание + +ПШ не обрабатывает запросы с сертификатом MTLS-соединения, по которому истёк срок жизни + +Если ПО клиента пытается верифицировать серверный сертификат банка, необходимо добавить в доверенные сертификат удостове + +Клиентский самоподписанный сертификат подписывает каждое тело запроса, которое клиент направляет на тестовой среде с помо + +Чтобы получить этот сертификат, необходимо самостоятельно сгенерировать ключевую пару client.crt и client.key: + +• client.crt — сертификат, который клиент передаёт в банк, чтобы зарегистрировать на тестовой среде + +• client.key — приватный ключ, который клиент оставляет у себя, чтобы подписывать тело запроса на тестовой среде + +Пример генерации запроса на ключевую пару client.crt и client.key с помощью OpenSSL: + +openssl req -x509 -newkey rsa:4096 -keyout private.key -out client.crt -nodes -days 3650 + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 1/7 + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/?rp-menuOpen=1 +https://217.12.103.132:2443/fsCryptoProxy +http://217.12.103.147:9914/fsCryptoProxy +https://217.12.103.147/fsCryptoProxy +https://alfabank.ru/sme/payservice/sbp/docs/welcome/?rp-menuOpen=1#authentication_process +mailto:acquiring@alfabank.ru + + +Пример заполнения полей: + +• Country Name (2 letter code) []: RU + +• State or Province Name (full name) []: + +• Locality Name (eg, city) []: Moscow + +• Organization Name (eg, company) []: COMPANY + +• Organizational Unit Name (eg, section) []: IT + +• Common Name (eg, fully qualified host name) []: Company Pay C2B + +• Email Address []: admin@test.ru + +Примечание + +• Длина RSA ключа может быть 2048 или 4096 бит + +• Ключевую пару генерируют на срок не менее 10 лет + +Файл client.crt необходимо направить в банк, чтобы зарегистрировать его на тестовой среде по адресу acquiring@alfabank.ru + +Вместе с файлом client.crt нужно указать: + +1. ИНН, наименование организации, на которую регистрируете сертификат + +2. Тип среды, для которой выпущен сертификат: тестовая или промышленная + +3. Информацию о том, как регистрируете сертификат: первично или повторно взамен истёкшего с alias… + +4. К письму обязательно приложите файл client.crt в архиве без пароля + +Пример письма: + +• Тема письма: +Регистрация сертификата на тестовом стенде СБП C2B + +• Тело письма: +Просим зарегистрировать сертификат, чтобы направлять запросы на тестовый стенд банка по продукту СБП C2B. +Сертификат выпущен впервые / повторно взамен истёкшего с alias… +Название организации: +ИНН: +Сертификат — во вложении. + +Письмо на регистрацию сертификата можно направить, если кликнуть на email-адрес acquiring@alfabank.ru. Тогда откроется предзап + +После регистрации сертификата на тестовой среде банк передаёт клиенту: + +1. Аlias — имя сертификата, который зарегистрирован на тестовой среде. Оно должно быть указано в headers — key-name при напра + +2. Клиентский сертификат RSA/TLS — он нужен, чтобы поднять MTLS-соединение на тестовой среде + +3. Сертификат удостоверяющего центра c2b-ca-test.crt вместе с промежуточным и удостоверяющим сертификатом root для тестово + +4. Тестовый номер терминала TermNo +Аутентификация на промышленной среде + +Взаимодействие с платёжным шлюзом Альфа-Банка на промышленной среде происходит через интернет по протоколу HTTPS, при + +Чтобы установить MTLS-соединение на промышленной среде, банк выдаёт клиенту ключевую пару RSA/TLS — сертификат и приватн + +Внимание + +ПШ не обрабатывает запросы с сертификатом MTLS-соединения, по которому истёк срок жизни + +Если ПО клиента пытается верифицировать серверный сертификат банка, необходимо добавить в доверенные сертификат удостове + +Клиентский самоподписанный сертификат подписывает каждое тело запроса, которое клиент направляет на промышленной среде + +Чтобы получить этот сертификат, клиенту необходимо самостоятельно сгенерировать ключевую пару client.crt и client.key: + +• client.crt — сертификат, который клиент передаёт в банк, чтобы зарегистрировать на промышленной среде + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 2/7 + +mailto:admin@test.ru +mailto:acquiring@alfabank.ru +mailto:acquiring@alfabank.ru + + +• client.key — приватный ключ, который клиент оставляет у себя, чтобы подписывать тело запроса на промышленной среде + +Пример генерации запроса на ключевую пару client.crt и client.key с помощью OpenSSL: + +Пример заполнения полей + +• Country Name (2 letter code) []: RU + +• State or Province Name (full name) []: + +• Locality Name (eg, city) []: Moscow + +• Organization Name (eg, company) []: COMPANY + +• Organizational Unit Name (eg, section) []: IT + +• Common Name (eg, fully qualified host name) []: Company Pay C2B + +• Email Address []: admin@test.ru + +Примечание + +• Длина RSA ключа может быть 2048 или 4096 бит + +• Ключевую пару генерируют на срок не менее 10 лет + +Файл client.crt необходимо направить в банк, чтобы зарегистрировать его на промышленной среде по адресу acquiring@alfabank.ru + +Вместе с файлом client.crt необходимо указать: + +1. ИНН, наименование организации, на которую регистрируете сертификат + +2. Тип среды, для которой выпущен сертификат: тестовая или промышленная + +3. Информацию о том, как регистрируете сертификат: первично или повторно взамен истёкшего с alias… + +4. К письму обязательно приложите файл client.crt в архиве без пароля + +• Тема письма: +Регистрация сертификата на промышленном (боевом) стенде СБП C2B + +• Тело письма: +Просим зарегистрировать сертификат, чтобы направлять запросы на промышленный (боевой) стенд банка по продукту СБП C2B. +Сертификат выпущен впервые / повторно взамен истёкшего с alias… +Название организации: +ИНН: +Сертификат во вложении. + +Письмо на регистрацию сертификата можно направить, если кликнуть на email-адрес acquiring@alfabank.ru. Тогда откроется предзап + +После регистрации сертификата на промышленной среде банк передаёт клиенту: + +1. Аlias — имя сертификата, который зарегистрирован на промышленной среде. Оно должно быть указано в headers — key-name при + +2. Клиентский сертификат RSA/TLS — он нужен, чтобы поднять MTLS-соединение на промышленной среде + +3. Сертификат удостоверяющего центра c2b-ca.crt вместе с промежуточным и удостоверяющим сертификатом root для промышлен + +4. Эндпойнт промышленной среды + +Тестирование + +Чтобы провести тестирование, клиент может использовать тестовый стенд. + +Эндпойнт тестовой среды (маршрут отправки) — https://217.12.103.132:2443/fsCryptoProxy + +Для направления запросов обязательны следующие headers: + +openssl req -x509 -newkey rsa:4096 -keyout private.key -out client.crt -nodes -days 3650 + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 3/7 + +mailto:admin@test.ru +mailto:acquiring@alfabank.ru +mailto:acquiring@alfabank.ru +https://217.12.103.132:2443/fsCryptoProxy + + +• Content-Type — application/x-www-form-urlencoded + +• Authorization — помещается hash полученного тела запроса + +• key-name — помещается alias зарегистрированного самоподписанного клиентского сертификата + +На тестовой среде взаимодействие происходит по протоколу HTTPS. + +Пример, как можно направить запрос на тестовом стенде + +1. Составить тестовый запрос. + +Порядок параметров в строке для вычисления hash должен соответствовать порядку, в котором параметры передаются в запрос + +Пример, как сформировать блок данных: + +Обязательно + +В блоке данных для подписи сообщения нужно исключить все пробелы, символы табуляции и переноса строки между ключа + +Примечание по полю «paymentPurpose»: + +• Максимальная длина значения paymentPurpose — 140 символов + +• Для значения paymentPurpose можно использовать такие символы: + +• Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065–090] и [097–122] в кодировке UTF-8 + +• Символы русского алфавита (А–Я и а–я) с десятичными кодами из диапазона [1040–1103] в кодировке UTF-8 + +• Цифры 0–9 с десятичными кодами из диапазона [048–057] в кодировке UTF-8 + +• Специальные символы с десятичными кодами из диапазонов [032–047], [058–064], [091–096], [123–126] в кодировке UTF-8 + +• Символ № под номером 8470 в кодировке UTF-8 + +• Символы ё с кодом 1105 и Ё с кодом 1025 не входят в допустимый диапазон для методов СБП API. Если paymentPurpose исполь + +• Нельзя переводить каретку и знак табуляции НСПК допускает символы \ и n, но, чтобы совместно использовать их в JSON, н + +• paymentPurpose: Платеж по дог\nовору… — неправильно + +• paymentPurpose: Платеж по дог\\nовору… — правильно + +{ + +"command":"GetQRCd", + +"TermNo":"90080567", + +"qrcType":"01", + +"amount":"100", + +"currency":"RUB", + +"paymentPurpose":"Назначение платежа" + +} + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 4/7 + + + +2. Из готового запроса необходимо вычислить hash по функции sha256 и зашифровать его приватным ключом тестовой среды + +Рассчитать и закрыть hash приватным ключом с помощью такой команды: + +Рассмотрим пример с использованием библиотеки OpenSSL: + +• client.key — имя файла приватного ключа + +• signature.txt — имя файла, в который будет записан зашифрованный hash + +• block.txt — имя файла с блоком данных, необходимых, чтобы рассчитать hash + +Десериализовать полученные байты в base64 при помощи команды: + +• signature64.txt — имя файла, в который будет записан зашифрованный hash по стандарту base64 + +Готовую строку нужно поместить в заголовок Authorization. + +3. Проверить результат можно так: + +Извлечь открытый ключ из сертификата client.crt командой: + +• client.crt — имя файла клиентского сертификата + +• signing-pub.key — имя файла, который получает открытый ключ + +С открытым ключом можно проверить данные командой: + +• signature.txt — имя файла, в который записан зашифрованный hash + +• signing-pub.key — имя файла открытого ключа + +• block.txt — имя файла с блоком данных, по которому рассчитан hash + +Если проверка прошла успешно, придёт ответ Verified OK. + +Примечание + +• Команда для проверки кодировки: file -bi block.txt + +• Команда для проверки символа новой строки в конце: cat -e block.txt + +• Команда для удаления символа новой строки в конце: truncate -s -1 block.txt + +Пример поля в составе запроса: + +Клиент отправляет запрос с заголовком autorization и сообщением, которое подписано приватным ключом клиента client.key и загол + +openssl dgst -sha256 -sign client.key -out signature.txt block.txt + +base64 signature.txt > signature64.txt + +openssl x509 -in client.crt -pubkey -noout > signing-pub.key + +openssl dgst -sha256 -signature signature.txt -verify signing-pub.key block.txt + +Content-Type: application/x-www-form-urlencoded + +Authorization: QMm5QWnAAj8Tp1hoIvGf1Hv7RPBoGgsDyGiR5GQ2v/MaS7Yaix6LDwAcry0UBWDZzqle2hx2fC7WbWkxXGvxK2Hcx + +key-name: c2b-tsp-test + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 5/7 + + + +Body: + +Как провести тестовую оплату + +1. Откройте на смартфоне ссылку https://testpay.alfabank.ru/sbp-page и нажмите Сканировать QR + +2. Наведите камеру смартфона на QR-код + +3. Нажмите Произвести оплату. +Готово: оплата на тестовом контуре выполнена. Переходить в выбор банков не надо. + +{"command":"GetQRCd","TermNo":"30000018","qrcType":"01","amount":"100","currency":"RUB","paymentPurpose" + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 6/7 + +https://testpay.alfabank.ru/sbp-page + + +Получение статуса платежа по QR-коду, который уже оплачен + +Получить статус платежа по QR-коду можно с помощью запроса GetQRCstatus или callback-уведомления от ПШ. + +Запрос GetQRCstatus позволяет получить статус по оплаченному динамическому QR-коду, кассовой платёжной ссылке или при опла + +Callback-уведомление уходит по оплаченному статическому и динамическому QR-коду, по кассовой платёжной ссылке или при опла + +Чтобы получать callback-уведомления, торгово-сервисному предприятию (далее — ТСП) необходимо направить на email acquiring@alf + +Сервер на стороне ТСП должен быть публичным, иметь протокол HTTPS и 443 порт. + +Адреса, с которых ПШ отправляет callback-уведомления: 217.12.97.124, 217.12.101.32. + +Дополнительная информация по вызову метода GetQRCstatus + +• В интеграционном тестовом окружении для метода GetQRCstatus введено ограничение частоты запросов: не более 4 запросов в м + +• Ограничение введено в связи с лимитами на стороне НСПК (Национальная система платёжных карт): общий лимит — 60 запросов в + +• Чтобы исключить паразитический/избыточный трафики обеспечить стабильность работы тестового контура, мы выделили для да + +• При превышении лимита запросы будут отвергаться кодом 429 (Too Many Requests). + +Переход на промышленную среду + +Чтобы перейти на промышленную среду, необходимо заключить сделку по СБП с Альфа-Банком и запросить боевые доступы — для + +Пример письма есть в разделе Аутентификация на промышленной среде + +Срок, за который банк предоставит боевые данные, — до трёх рабочих дней. + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 7/7 + +mailto:acquiring@alfabank.ru + diff --git a/_docs/alfabank/qr_payout/2_general_provisions.md b/_docs/alfabank/qr_payout/2_general_provisions.md new file mode 100644 index 0000000..3af0134 --- /dev/null +++ b/_docs/alfabank/qr_payout/2_general_provisions.md @@ -0,0 +1,275 @@ + +Общие положения + +Каналы взаимодействия + +1. Взаимодействие с хостом Альфа-Банка осуществляется через сеть Интернет по протоколу HTTP(S) с использованием клиентских +сертификатов RSA/TLS. + +2. Порядок выпуска, установки и применения сертификатов определяется Удостоверяющим Центром Заказчика и не является пред +данных ТУ, за исключением требований к имени (алиас) сертификатов на прокси-сервере Заказчика: + +• Имя (алиас) сертификата должно соответствовать коду терминала запроса и реквизиту заголовка запроса key-name; + +• При проверке соединения используется сертификат с именем равным обязательному параметру TermNo тела запроса и реквиз +заголовка запроса key-name. + +Идентификация Виртуального терминала + +Описание по идентификации + +1. Каждый виртуальный терминал получает регистрационный номер (далее — «TermNo»). + +2. TermNo требуется для определения виртуального терминала, кассы или системы. + +3. Для каждого адреса ТСП присваивается минимум 1 виртуальный терминал и максимум по запросу. + +4. TermNo определяет принадлежность терминала ЮЛ и конкретному ТСП, а также расчетный счет ЮЛ в системе Заказчика, на кото +будут поступать средства покупателей. + +5. TermNo сохраняется в настройках виртуального терминала и с клиентским сертификатом используется в информационном обмен +на прикладном уровне протокола взаимодействия. + +6. Оплата производится покупателями самостоятельно, необходимая для оплаты информация передается покупателю посредством +кода СБП, отображаемом на экране Агент ТСПа, или распечатанном на чеке или кассе или ссылке и т. д. + +7. Получение динамических QR-кодов СБП и проверка их оплаты осуществляются с обязательным использованием TermNo. + +Общий порядок работы + +Оплата покупки через СБП + +1. Кассир указывает на терминале (в случае кассового решения получает из ПО кассы) следующие параметры: + +• Сумма; + +• Валюта (подставляются автоматически); + +• Назначение платежа (подставляется автоматически). + +2. ТСП запрашивает динамический QR-код; + +3. ТСП отображает полученное изображение (или печатает предварительный чек с изображением); + +4. Покупатель: + +• сканирует QR-код в приложении своего смартфона; + +• получает и проверяет необходимую для подтверждения доп. информацию; + +• подтверждает оплату; + +• сообщает о проведении оплаты кассиру. + +5. Кассир на терминале запрашивает подтверждение оплаты; + +6. ТСП запрашивает подтверждение оплаты полученного ранее QR-кода + +12/23/25, 11:21 AM Общие положения + +https://alfabank.ru/sme/payservice/sbp/docs/general/?rp-menuOpen=1 1/4 + + + +7. Получив подтверждение, ТСП печатает чек оплаты QR-кода с указанием: + +•  qrcId + +• кода транзакции СБП + +• даты и времени оплаты QR-кода +Возврат покупки через СБП + +Особенность возврата покупки через ТСП: + +1. Требует обязательного наличия чека и указания кода транзакции СБП; + +2. Может производиться исключительно: + +• по идентификатору плательщика (номеру телефона), осуществившего оплату; + +• возврат средств возможен только в Банк-участник СБП из которого проводилась оплата; + +• возврат осуществляется на счет плательщика, предназначенный для приема переводов СБП (счет по умолчанию для номера +телефона получателя). + +Кассир указывает на терминале следующие параметры: + +1. Сумма возврата покупки (частичного возврата); + +2. Валюта; + +3. Назначение платежа; + +4. Данные из чека оплаты QR-кода покупателя: + +• Код транзакции СБП; + +• qrcId; + +• Дату оплаты QR-кода. + +ТСП запрашивает возможность возврата оплаты QR-кода; + +После подтверждения возможности возврата: + +• На хосте Банка найдена исходная операция и имеются все необходимые данные для возврата, кассир указывает на терминале +одноразовый код подтверждения возврата (порядок получения кассиром одноразового кода подтверждения (SMS/PUSH сообще +или производится иная аутоинтефикация ответственного пользователя, обладающего правом выполнения подобны действий. + +• Любой способ проверки полномочий сотрудника ЮЛ совершать возвраты, если таковой необходим оговаривается отдельно. + +ТСП запрашивает возврат и печатает чек возврата с указанием: + +Данные из чека оплаты QR-кода покупателя: * Код транзакции «payrnn»; * Сумма возврата, может быть меньше или равна сумме, +указанной в чеке оплаты; * Конечный список используемых при возврате параметров может быть измен, оговаривается отдельно. + +Регистрация кассовой ссылки + +• ТСП отправляет запрос на создание кассовой ссылки Агенту ТСП; + +• Агент ТСП отправляет запрос на создание кассовой ссылки в ОПКЦ СБП; + +• ОПКЦ СБП возвращает данные новой Кассовой ссылки Агенту ТСП; + +• Агент ТСП передает данные Кассовой ссылки в ТСП + +• Агент ТСП размещает QR-код с данными Кассовой ссылки у кассы или иными аналогичными способами для возможности считыва +его электронными устройствами клиентов (смартфон, планшет и т. п.) в процессе оплаты ими покупок. + +Активация кассовой ссылки + +1. ТСП направляет запрос на активацию Кассовой ссылки Агенту ТСП; + +• В запросе активации ТСП передает идентификатор ранее зарегистрированной кассовой ссылки и параметры оплаты; + +• В параметрах оплаты обязательно следует передавать сумму платежа, валюту платежа и назначение платежа, а также другие +служебные параметры запроса, описанные в спецификации. + +• Для получения уведомлений о статусе оплаты по активированной ссылке ТСП должно передать в специальном параметре запр +активации адрес для коллбеков с уведомлением от НСПК о статусе операций оплаты. + +2. Агент ТСП передает запрос на активацию Кассовой ссылки в ОПКЦ СБП; + +12/23/25, 11:21 AM Общие положения + +https://alfabank.ru/sme/payservice/sbp/docs/general/?rp-menuOpen=1 2/4 + + + +3. ОПКЦ СБП передает Агенту ТСП уведомление об активации Кассовой ссылки; + +4. Агент ТСП передает в ТСП уведомление об активации Кассовой ссылки; + +5. ТСП сообщает клиенту о возможности оплаты по QR-коду, полученного в процессе создания (регистрации) кассовой ссылки, кото +клиент может считать с помощью своего электронного устройства; + +6. Клиент производит оплату C2B с помощью своего электронного устройства; + +7. Агент ТСП получает уведомление от НСПК о финальном статусе операции C2B; + +8. ТСП запрашивает статус операции у Агента ТСП или получает уведомление о статусе операции в случае, если ранее в запросе +активации кассовой ссылки был передан адрес для коллбеков с уведомлением о статусе оплат. + +Деактивация кассовой ссылки + +1. Клиент или ТСП принимает решение об отсутствии возможности или необходимости оплаты по ранее активированной кассовой +ссылке; + +2. ТСП отправляет запрос Агенту ТСП на деактивацию кассовой ссылки; + +3. Агент ТСП передает запрос на деактивацию Кассовой ссылки в ОПКЦ СБП; + +4. ОПКЦ деактивирует ссылку и передает Агенту ТСП оповещение об этом; + +5. Агент ТСП передает оповещение о деактивации ссылки в ТСП. + +Возврат по ранее оплаченной кассовой ссылке + +a) Для возврата по ранее оплаченной кассовой ссылке отличий от ранее реализованных процессов возврата по операциям C2B нет +за исключением того, что обязательно требуется передавать значение параметра «payrrn» без «qrcid». + +Изменение счета ТСП для ранее зарегистрированной кассовой ссылки + +a) ТСП принимает решение о необходимости смены счета, который был использован в процессе создания (регистрации) кассовой +платежной ссылки; + +b) ТСП обращается с запросом о изменении счета по ранее зарегистрированной кассовой ссылке к Агенту ТСП; + +c) Агент ТСП передает запрос о смене счета в НСПК; + +d) НСПК сообщает о результате выполнения запроса Агенту ТСП; + +e) ТСП уточняет статус операции смены счета у Агента ТСП. Автоматического уведомления ТСП о смене счета по ранее +зарегистрированной кассовой ссылки не поддерживается. + +Регистрация QR-кода для привязки счета + +1. ТСП регистрирует QR-код с типом «03» для привязки счета клиента к функциональности оплат по инициативе ТСП; + +2. Агент ТСП передает запрос на регистрацию QR-кода для привязки счета в НСПК; + +3. Клиент считывает QR-код при помощи своего электронного устройства; + +4. Банк Плательщика получает данные QR-кода из запроса в НСПК; + +5. Банк Плательщика отображает детали привязки счета на электронном устройстве Клиенту; + +6. Клиент принимает решение о привязке счета; + +7. Банк плательщика сообщает о решении клиента в НСПК; + +8. НСПК сообщает Агенту ТСП о решении по привязке счета; + +9. ТСП получает уведомление о статусе совершенной Плательщиком привязки счета в случае, если в запросе на регистрацию QR-ко +был передан адрес для коллбеков. + +Регистрация QR-кода для оплаты с привязкой счета + +1. ТСП регистрирует QR-код для оплаты как описано в пункте «Оплата покупки через СБП», но с дополнительным параметром +«subscriptionPurpose»; + +2. После успешного завершения оплаты по QR-коду Банк Плательщика должен инициировать на электронном устройстве клиента +сценарий получения решения клиента по привязке счета для оплат по инициативе ТСП, оплату в пользу которого только что сов +клиент; + +3. Банк Плательщика отображает детали привязки счета на электронном устройстве Клиенту; + +12/23/25, 11:21 AM Общие положения + +https://alfabank.ru/sme/payservice/sbp/docs/general/?rp-menuOpen=1 3/4 + + + +4. Клиент принимает решение о привязке счета; + +5. Банк плательщика сообщает о решении клиента в НСПК; + +6. НСПК сообщает Агенту ТСП о решении по привязке счета; + +7. ТСП получает уведомление о статусе совершенной Плательщиком привязки счета в случае, если в запросе на регистрацию QR-ко +был передан адрес для коллбеков. + +Оплата с привязанного счета по инициативе ТСП + +1. ТСП регистрирует QR-код для оплаты с привязанного счета; + +2. Агент ТСП передает запрос регистрации QR в НСПК; + +3. ТСП направляет запрос оплаты с привязанного счета в НСПК; + +4. НСПК направляет запрос оплаты с привязанного счета в Банк Плательщика; + +5. Банк Плательщика сообщает о своем решении по оплате с привязанного счета своего клиента в пользу ТСП из запроса НСПК; + +6. НСПК Сообщает Агенту ТСП о решении Банка плательщика об оплате с привязанного счета; + +7. Банк Плательщика начинает операцию C2B; + +8. НСПК уведомляет Агента ТСП о финальном статусе операции C2B. + +12/23/25, 11:21 AM Общие положения + +https://alfabank.ru/sme/payservice/sbp/docs/general/?rp-menuOpen=1 4/4 + + diff --git a/_docs/alfabank/qr_payout/3_static_QR-cods.md b/_docs/alfabank/qr_payout/3_static_QR-cods.md new file mode 100644 index 0000000..e30e7bd --- /dev/null +++ b/_docs/alfabank/qr_payout/3_static_QR-cods.md @@ -0,0 +1,765 @@ +Статический QR-код + +Статический QR-код + +Оплата по статическому QR-коду — это один из способов безналичной оплаты, альтернатива платежам совершаемых банковскими к + +Статический QR-код представляет из себя изображение, которое можно распечатать и разместить на видном месте возле кассовой + +Изображение такого QR-кода всегда остается неизменным. + +Данный вид QR-кода реализован в двух вариантах: + +• с открытой суммой, которую вводит сам покупатель; + +• с фиксированной суммой, заполняемой продавцом. + +Совершить оплату по статическому QR-коду возможно следующими способами: + +• отсканировать изображение QR-кода камерой смартфона и далее перейти в приложение мобильного банка или отсканировать не +приложения банка; + +• в случае если изображение QR-кода содержит NFC-метку, то приложить смартфона с включенным NFC-модулем и совершить опл + +Если QR-код уже с фиксированной суммой, то произвести оплату по цене, указанной в реквизитах платежа, если сумма открытая, то + +Средства мгновенно поступают на счёт продавца. + +Терминал или дополнительное устройство в данном случае не требуется. + +1. Запрос на регистрацию статического QR-кода + +Метод GetQRCd + +• Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1… + +50) + +y Тип запроса. Константа «GetQRCd». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcType String (n-2) y Тип запрашиваемого QR-кода — «01». + +amount Number o Сумма платежа в минорных единицах (копейках). + +Значение не указывается, если сумма по платежу вводится плательщиком (сумма открыта). + +width String o Ширина картинки QR-кода (только числовое значение). + +height String o Высота картинки QR-кода (только числовое значение). + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). + +paymentPurpose String (ans- +140) + +o Назначение платежа. + +redirectUrl String (ans- + +1024) + +о Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. Допускаются только си + +соответствовать правилам кодировки URL. + +Если все же требуется использовать в redirectUrl кириллические символы, необходимо перекодировать + +encoded octets согласно RFC3986. + +messageID String (ans- + +1024) + +o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 1/9 + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 + + +Код ключа Тип данных required Назначение + +queryData.notificationUrl String (ans- + +512) + +o Полный URL для получения уведомления о финальном статусе оплаты QR-кода. Если параметр отсутс + +• Примерный формат запроса: + +• Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +image String (an) + +Длинна зависит от формата, порядок 7000 символов. + +y Изображение QR-кода содержит энкодированный BASE64 файл из + +message String (ans-1024) y Расшифровка кода ответа**. + +payload String (1…999) y Платежная ссылка***. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +qrcId String (an-32) y Идентификатор QR-кода. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. + +status String (an-20) y Статус регистрации Платежной ссылки СБП. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +- https://qr.nspk.ru/AS10000NJTDV88TN82CRT8CG1AU690OF + +- https://qr.nspk.ru/AS10000NJTDV88TN82CRT8CG1AU690OF?type=01&bank=100000000008&sum=100&cur=RUB&crc=2D0D + +• Примерный формат ответа: + +• 200 ОК + +1 { + +2 "command":"GetQRCd", + +3 "TermNo":"90080567", + +4 "qrcType":"01", + +5 "width":"600", + +6 "height":"600", + +7 "amount":"10000", + +8 "currency":"RUB", + +9 "paymentPurpose":"Назначение платежа", + +10 "messageID":"message", + +11 "queryData": + +12 { + +13 "notificationUrl":"https://sbp-payments" + +14 }, + +15 "redirectUrl": " https://exampletsp.io/qwertyui " + +16 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "image": "iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIKFIRoUEQWVNAAAQA/w…...YII", + +5 "message": "OK", + +6 "messageID": "message", + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 2/9 + +https://qr.nspk.ru/AS10000NJTDV88TN82CRT8CG1AU690OF +https://qr.nspk.ru/AS10000NJTDV88TN82CRT8CG1AU690OF?type=01&bank=100000000008&sum=100&cur=RUB&crc=2D0D + + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +2. Нотификация о финальном статусе оплаты статического QR-кода + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н + +Метод «qrc/notification» + +• Описание параметров запроса: + +Код ключа Тип данных required Назначение + +qrcId String (an-32) y Идентификатор QR-кода. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +status String (an-10) y Статус оплаты QR-кода в НСПК. + +Возможные значения: + +— ACWP — ACCEPTED операция завершена успешно; + +— RJCT — REJECTED операция отклонена. + +amount Number y Сумма платежа в минорных единицах (копейках). + +timestamp YYYY-MMDDThh: mm: ss[.SSS] + +или + +YYYY-MMDDThh: mm: + +ss[.SSSZ] + +y Метка времени НСПК по Гринвичу (GMT). + +payerId String (ans) y Идентификатор плательщика (маскированный номер телефона плательщика). + +kzo String (ans 1-128) y Контрольное Значение Операции СБП. + +Формируется ОПКЦ СБП. Присутствует при условии, что Операция СБП C2B по запрашиваемом + +="ACWP»). + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +CreditDatePos String (ans 1-256) o Дата операции, установленная Банком Получателя в ходе обработки уведомления НСПК. + +• Примерный формат запроса: + +7 "payload": "https://qr.nspk.ru/AS10000NJTDV88TN82CRT8CG1AU690OF", + +8 "payrrn": "000051992395", + +9 "qrcId": "AS10000NJTDV88TN82CRT8CG1AU690OF", + +10 "status": "CREATED" + +11 } + +{ + +"ErrorCode":"Код ответа", + +"message":"Расшифровка кода ответа" + +} + +1 { + +2 "command":"qrc/notification", + +3 "qrcId":"AS10000NJTDV88TN82CRT8CG1AU690OF", + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 3/9 + + + +• ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. +В настоящий момент ответ ВС не обрабатывается шлюзом Агента ТСП. Обработка ответов ТСП сейчас находится в разработк +В случае добавления со стороны НСПК дополнительных параметров уведомления, система, принимающая их от шлюза Альфа-Банк +неожиданные параметры как ошибочный запрос. + +3. Запрос проведения возврата по успешной оплате по статическому QR-коду + +Возврат по СБП состоит из 2х последовательных запросов: + +• GetQRCreversalData — проверка возможности проведения возврата; + +• QRCreversal — выполнение непосредственно самого возврата. + +В случае если ТСП инициирует выполнение повторных операций СБП B2C по одной и той же операции СБП C2B, то допускается не б +операций СБП B2C в течение одного операционного дня. + +3.1. Запрос возможности проведения возврата + +Запрос GetQRCreversalData направляется ТСП в Банк для проверки возможности возврата по ранее оплаченному QR-коду и получен + +Метод GetQRCreversalData + +• Описание параметров запроса: + +Код +ключа Тип данных required Назначение + +command String (an-1… +50) + +y Тип запроса. Константа GetQRCreversalData». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y Идентификатор QR-кода. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма возврата в минорных единицах (копейках). Если сумма возврата не передана, то значение будет принято зн + +возвратов. + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого значения валюта будет взята из данных о + +messageID String (ans- + +1024) + +o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +Примечание: Терминалы с подключенным сканером и распознаванием QR-кодов могут получить «qrcId», распарсив строку QR-кода +соответствует полю «payload». + +• Примерный формат запроса: + +4 "trxId":"A31040920067662400000550448AD7B3", + +5 "status":"ACWP", + +6 "amount":"10000", + +7 "timestamp":"2023-04-14T09:20:06.000Z", + +8 "payerId":"\*\*\*\*\*\*\*\*\*1779", + +9 "kzo":"580d2f38370f378db5915c047ba7b72014327ce455caa927b2488f224926daac85e82984c889d66e79dad8039ccdefd + +10 "payrrn":"000051992395", + +11 "TermNo":"90080567", + +12 "CreditDatePos":"20230414" + +13 } + +{ + +` `"command":"GetQRCreversalData", + +` `"TermNo":"90080567", + +` `"qrcId":"AS10000NJTDV88TN82CRT8CG1AU690OF", + +` `"trxId":"A31040920067662400000550448AD7B3", + +` `"trxDT":"20230414062006", + +` `"amount":"10000", + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 4/9 + + + +• Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +message String (ans-1024) y Расшифровка кода ответа**. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. + +Значение параметра возвращается в случае, если оно указано в запр + +payerBnkBIC String (n-9) y БИК банка получателя. + +payerBnkName String (an-50) y Наименование банка получателя. + +payerId String (n-13) y Идентификатор получателя (маскированный номер телефона получате + +payerPam String (ans 1…140) y PAM получателя. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +qrcId String (an-32) y Идентификатор QR-кода. + +trxDT String (n-14) y Дата и время платежа по Гринвичу (GMT). + +Формат времени — ГГГГММДДччммсс. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +• Примерный формат ответа: + +• 200 ОК + +Примечание: + +• Текстовые данные передаются в формате urlencoded; + +• В случае получения "message»: «Получен отказ на запрос возврата. Статус Recall, ErrDebetMerchant: KSM0284 Invalid special cond +счёт ТСП. Он должен быть положительным и без ограничений. + +• 400 Bad Request + +` `"currency":"RUB", + +` `"messageID":"message" + +} + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "message": "OK", + +5 "messageID": "message", + +6 "payerBnkBIC": "044525593", + +7 "payerBnkName": "%u0410%u043B%u044C%u0444%u0430%20%u0411%u0430%u043D%u043A", + +8 "payerId": "*1779", + +9 "payerPam": "%u0424%u0421%u0418", + +10 "payrrn": "000051992395", + +11 "qrcId": "AS10000NJTDV88TN82CRT8CG1AU690OF", + +12 "trxDT": 20230414062006 + +13 "trxId": "A31040920067662400000550448AD7B3" + +14 } + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 5/9 + + + +3.2. Запрос возврата оплаты по QR-коду + +Запрос QRCreversal направляется ТСП в Банк для возврата по ранее произведенной оплате QR. Возврат производится только на сче +возврата (метод GetQRCreversalData). + +Метод QRCreversal. + +• Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1… +50) + +y Тип запроса. Константа «QRCreversal». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y Идентификатор QR-кода. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма платежа в минорных единицах (копейках). Если сумма возврата не передана, то значение будет + +совершенных возвратов. + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого значения валюта будет взята + +messageID String (ans- + +1024) + +o Уникальный идентификатор сообщения, GUID из сообщения «GetQRCreversalData». Обязательно если + +queryData.notificationUrl String (ans-512) o Полный URL для получения уведомления о финальном статусе возврата QR-кода. Уведомление не про + +* messageID — необходимо передавать точное значение, которые было указано в ответе на запрос GetQRCreversalData. Если значени +запрос GetQRCreversalData с указанием messageID и затем использовать полученный GUID при запросе на возврат. + +• Примерный формат запроса: + +• Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответ*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +{ + +"ErrorCode":"Код ответа", + +"message":"Расшифровка кода ответа" + +} + +1 { + +2 "command":"QRCreversal", + +3 "TermNo":"90080567", + +4 "qrcId":"AS10000NJTDV88TN82CRT8CG1AU690OF", + +5 "trxId":"A31040920067662400000550448AD7B3", + +6 "trxDT":"20230414062006", + +7 "amount":"10000", + +8 "currency":"RUB", + +9 "messageID":"message" + +10 "queryData": + +11 { + +12 "notificationUrl":"http://sbp-refunds" + +13 } + +14 } + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 6/9 + + + +Код ключа Тип данных required Назначение + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +message String (ans-1024) y Расшифровка кода ответа. + +messageID String (ans-1024) y/o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +trxDT String (n-14) y Дата и время совершенного возврата по Московскому времени (MSK). + +Формат времени — ГГГГММДДччммсс. + +trxId String (an-32) y Уникальный идентификатор операции возврата в НСПК. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +• Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +{ "ErrorCode":"Код ответа", "message":"Расшифровка кода ответа" } + +4. Запрос статуса возврата СБП (B2C) + +Метод «GetQRCreversalStatus» необходим ТСП для уточнения статуса операции B2C (метод QRCreversal). + +В запросе «GetQRCreversalStatus» обязательно должна быть передана пара параметров: + +1. «payrrn» или «originalTrxId» + +Один из параметров «payrrn» или «originalTrxId» используется для нахождения исходного платежа C2B. + +2. «trxId» или «messageID». + +Один из параметров «trxId» или «messageID» используется для нахождения операции возврата B2C, по которому требуется уточнит + +Метод «GetQRCreversalStatus» + +• Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «Ge + +TermNo String (an-20) y Уникальный идентификатор + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "currency": "RUB", + +6 "message": "%u0412%u043E%u0437%u0432%u0440%u0430%u0442%20%u043F%u0440%u043E%u0432%u0435%u0434%u043 + +7 "messageID": "message", + +8 "payrrn": "000051992395", + +9 "trxDT": 20230414093406, + +10 "trxId": "B31071502287201D00001650448AD7B3" + +11 } + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 7/9 + + + +Код ключа Тип данных required Назначение + +payrrn String (n-12) y/o + +(обязательно, если не передан параметр «originalTrxId») + +Значение параметра «payrrn + +originalTrxId String (an-32) y/o + +(обязательно, если не передан параметр «payrrn») + +Идентификатор исходной оп + +trxId String (an-32) y/o + +(обязательно, если не передан «messageID») + +Уникальный идентификатор + +messageID String (ans-1024) y/o + +(обязательно, если не передан «trxId») + +Значение параметра «messa + +• Примерный формат запроса: + +• Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ошибки*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +Url String (ans 1-512) o Полный URL получения уведомления для ТСП -значение параметра, переданного при запросе возврата Q + +amount Number y Сумма Операции СБП в копейках. Целое, положительное число. Валюта операции — рубли РФ. + +message String (ans-1024) y Описание результата выполнения запроса**. + +messageID String (an-32) o Значение параметра «messageID» из запроса «QRCreversal». + +originalQrcId String (an-32) y Идентификатор зарегистрированной Платежной ссылки СБП, по которому была выполнена исходная Опе + +originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B. + +payerId String (an-13) y Маскированный номер телефона Клиента-Получателя (Плательщика в исходной Операции C2B, кому дел + +status String (an-4) y Статус операции возврата СБП (B2C): + +ACWP — ACCEPTED операция завершена успешно; + +RJCT — REJECTED операция отклонена; + +NTST — Статус операции неизвестен. + +trxDT String (n-14) y Дата и время выполнения Операции СБП B2C по сценарию «Возврат по Операции СБП C2B» (ГГГГММДД + +trxId String (an-32) y Уникальный идентификатор операции возврата в НСПК. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +• Примерный формат ответа: + +{ + + "command": "GetQRCreversalStatus", + + "TermNo": "90080567", + + "payrrn": "000051992395", + + "originalTrxId": "A31040920067662400000550448AD7B3", + + "trxId": "B31071502287201D00001650448AD7B3", + + "messageID":"message" + +} + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 8/9 + + + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "message": "OK", + +6 "messageID":"123Rersal_Num567", + +7 "originalQrcId": "AS10000NJTDV88TN82CRT8CG1AU690OF", + +8 "originalTrxId": "A31040920067662400000550448AD7B3", + +9 "payerId": "*********1779", + +10 "URL":"http://sbp-payment/status", + +11 "status": "ACWP", + +12 "trxDT": 20230414093406, + +13 "trxId": "B31071502287201D00001650448AD7B3" + +14 } + +{ + +"ErrorCode":"Код ответа", + +"message":"Расшифровка кода ответа" + +} + +12/23/25, 11:22 AM Статический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/static/?rp-menuOpen=1 9/9 + + diff --git a/_docs/alfabank/qr_payout/4_dynamic_QR-cods.md b/_docs/alfabank/qr_payout/4_dynamic_QR-cods.md new file mode 100644 index 0000000..be1e427 --- /dev/null +++ b/_docs/alfabank/qr_payout/4_dynamic_QR-cods.md @@ -0,0 +1,1399 @@ + +Динамический QR-код + +Динамический QR-код + +Оплата по динамическому QR-коду — это один из способов безналичной оплаты, альтернатива платежам совершаемых банковскими + +Динамический QR-код создается отдельно под каждую конкретную покупку, поэтому он сразу содержит стоимость покупки и все не + +Для генерации динамического QR-кода необходимо устройство: компьютер, смартфон или терминал. Чтобы провести оплату касси +мобильного телефона или через банковское приложение, подтверждает оплату. Средства мгновенно поступают на счёт продавца. + +1. Запрос на регистрацию динамического QR-кода + +Метод GetQRCd + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCd». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcType String (n-2) y Тип запрашиваемого QR-кода — «02». + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +OrderNumber String (ans-1000) o Номер заказа. + +В параметре должны передаваться только английские буквы и/или арабские + +width String o Ширина картинки QR-кода (только числовое значение). + +height String o Высота картинки QR-кода (только числовое значение). + +paymentPurpose String (ans-140) o Назначение платежа. + +messageID String (an-1…1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +qrTtl String (an-1…6) o Срок жизни Платежной ссылки СБП в минутах. + +Минимальное допустимое значение — «1». Максимальное допустимое значен + +Рекомендация: устанавливать срок жизни Платежной ссылки СБП не менее « + +queryData.notificationUrl String (ans-512) o Полный URL для получения уведомления о финальном статусе оплаты QR-ко + +Если параметр отсутствует, уведомление не производится. + +redirectUrl String (ans-1024) о Содержит ссылку для автоматического возврата в приложение или на сайт ТСП + +Если все же требуется использовать в redirectUrl кириллические символы, необх + +Блок для внесения д + +Код ключа Тип данных required + +extJsonParams Object o + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 1/16 + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 + + +Код ключа Тип данных required + +JsonParam1 String (ans-250) o + +JsonParam2 String (ans-250) o + +... ... ... + +JsonParam10 String (ans-250) o + +Если требуется сформировать динамический QR-ко + +Код ключа Тип +данных required Назначение + +subscriptionServiceId String (32) o Идентификатор привязки. Обязательно при наличии subscriptionServiceName, т. к. параметры subscriptionS + +их в ходе проверки данных привязки счёта на уникальность. + +subscriptionServiceName String (70) o Наименование привязки. Обязательно при наличии subscriptionServiceId, т. к. параметры subscriptionServic + +их в ходе проверки данных привязки счёта на уникальность. + +Если требуется сформировать динамический QR-код под о + +Код ключа Тип данных required Назначен + +queryData.SenderFIO String (an-140) o Фамилия, + +queryData.SenderID String (an-11.13) o Идентифи + +queryData.SenderBankBIC String (n-9) o БИК Банка + +* Блок для передачи дополнительных идентификаторов ТСП в ежедневные реестры СБП. Функционал потребует дополнительной н + +b) Примерный формат запроса: + +1 { + +2 "command":"GetQRCd", + +3 "TermNo":"90080567 ", + +4 "qrTtl":"5", + +5 "amount":"10000", + +6 "currency":"RUB", + +7 "qrcType":"02", + +8 "width":"600", + +9 "height":"600", + +10 "paymentPurpose":"Назаначение платежа", + +11 "OrderNumber":"FYI123456", + +12 "subscriptionServiceId":"3842ca282aea11e88feca860b60304d5", + +13 "subscriptionServiceName":"Подписка на онлайн-кинотеатр", + +14 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +15 "redirectUrl": "https://alfabank.ru/sme/payservice/sbp/", + +16 "extJsonParams": + +17 { + +18 "JsonParam1":"Value", + +19 "JsonParam2":"Value", + +20 "JsonParam3":"Value", + +21 "JsonParam4":"Value", + +22 "JsonParam5":"Value", + +23 "JsonParam6":"Value", + +24 "JsonParam7":"Value", + +25 "JsonParam8":"Value", + +26 "JsonParam9":"Value", + +27 "JsonParam10":"Value" + +28 }, + +29 "queryData": + +30 { + +31 "notificationUrl":"https://sbp-payments", + +32 "SenderFIO":"Иванов|Иван|Иванович", + +33 "SenderID":"0079123456789", + +34 "SenderBankBIC":"44525593" + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 2/16 + + + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначен + +ErrorCode String (an-20) y Код ответа + +TermNo String (an-20) y Уникальны + +image String (an) + +Длинна зависит от формата, порядок 7000 символов. + +y Изображен + +message String (ans-1024) y Расшифро + +messageID String (ans-1024) o Уникальны + +Значение + +payload String (1…999) y Платежная + +payrrn String (n-12) y Референс + +qrcId String (an-32) y Идентифи + +status String (n-7) y Статус рег + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +- https://qr.nspk.ru/AD100026KQ0ESJBV8OFPCG0U9K1H52UM + +- https://qr.nspk.ru/AD100026KQ0ESJBV8OFPCG0U9K1H52UM?type=02&bank=100000000008&sum=10000&cur=RUB&crc=4244 + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request { "ErrorCode":"Код ответа", "message":"Расшифровка кода ответа" } + +2. Запрос статуса оплаты по динамическому QR-коду + +Запрос статуса GetQRCstatus направляется кассой/терминалом ТСП в Банк для получения статуса Операции оплаты выпущенного ра + +Запрос статуса направляется не ранее, чем через 10 секунд после формирования QR-кода и не чаще чем каждые 3 секунды. + +Успешный ответ на запрос статуса можно получить в течении 30 дней после совершения оплаты по данному QR-коду. + +В случае, если срок хранения данных истек, то в ответе на запрос вернется: + +35 } + +36 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "image":"iVBORw0KGgoAAAANSUhEUgAAghjysAAAAgjjafggkqqBEoAAARKCAIAAAQA/w……………..................Y + +5 "message": "OK", + +6 "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +7 "payload": "https://qr.nspk.ru/AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + +8 "payrrn": "000000022154", + +9 "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + +10 "status": "CREATED" + +11 } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 3/16 + +https://qr.nspk.ru/AD100026KQ0ESJBV8OFPCG0U9K1H52UM +https://qr.nspk.ru/AD100026KQ0ESJBV8OFPCG0U9K1H52UM?type=02&bank=100000000008&sum=10000&cur=RUB&crc=4244 + + +Метод GetQRCstatus + +• Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCstatus». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y/o Идентификатор QR-кода (обязательно, есл + +payrrn String (n-12) y/o Референсный идентификатор запроса в си + +messageID String (ans-1024) o Уникальный идентификатор сообщения, G + +• Примерный формат запроса: + +• Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +message String (ans-1024) y Расшифровка кода ответа**. + +qrcId String (an-32) y Идентификатор QR-кода. + +status String(an-10) y Статус оплаты QR-кода в НСПК***. + +Возможные значения: + +1. ACWP — ACCEPTED операция завершена успешно; + +2. RJCT — REJECTED операция отклонена; + +3. NTST — NOT_STARTED операции по QR коду не существует; + +4. RCVD — RECEIVED операция в обработке. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +trxDT String (n-14) y Дата и время платежа по Гринвичу. + +Формат — ГГГГММДДччммсс. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +CreditDatePos String (ans 1-256) y Дата операции, установленная Банком Получателя (ГГГГММДД) + +TermNo String (an-20) y Уникальный идентификатор терминала. + +{ + +"ErrorCode":999, + +"message":"Неизвестный код проблемы 999RQ05014" + +} + +{ + + "command":"GetQRCstatus", + + "TermNo":"90080567", + + "qrcId":"AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + + "payrrn":"000000022154", + + "messageID": "message" + +} + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 4/16 + + + +Код ключа Тип данных required Назначение + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). + +Url String (ans 1-512) o Полный URL для получения уведомления ТСП о финальном статусе оплаты QR-кода. Зн + +payerId String (n-13) y Идентификатор плательщика (маскированный номер телефона плательщика). + +Kzo String (ans 1-128) o Контрольное Значение Операции СБП. + +Формируется на стороне НСПК. + +Присутствует при условии, что Операция СБП C2B по запрашиваемому qrcId заверше + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. + +Значение параметра возвращается в случае, если оно указано в запросе. + +merchantId String (12) o ID мерчанта (ТСТ) в Банке + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +Примечание: + +• Успешно оплаченным считается только QR-код, для которого получен «status» = «ACWP» с идентификатором платежа «trxId» и «E + +• В случае если получен «status» = «NTST» — означает необходимость повтора запроса до получения одного из финальных статусов + +• Получение «status» = «RJCT» означает отказ в оплате данного QR-кода. + +— Примерный формат ответа: + +• 200 OK + +Примечание: + +• Текстовые данные передаются в формате urlencoded. + +• В поле " trxDT» содержится дата и время транзакции на ПШ Банка в формате ГГГГММДДччммсс. + +В случае получения значения trxId = null необходимо повторить запрос. Отсутствие значения означает, что в СБП еще нет успешного + +• 400 Bad Request + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + +5 "status": "ACWP", + +6 "trxId": "A3013090427361010000057B3DA2D4A7", + +7 "trxDT": "20230113090427", + +8 "payrrn": "000000022154", + +9 "CreditDatePos": "20230113", + +10 "TermNo": 90080567, + +11 "amount": 10000, + +12 "currency": "RUB", + +13 "Url":"https://sbp-payments", + +14 "payerId": "*********1234", + +15 "kzo": "212b906a810f2562fd88e145199b30f4b4ea5c7cd7d0261236a73a6152f07f56b7feb915712a055522ee9b76 + +16 "messageID": "message", + +17 "merchantId": "MB0000009603" + +18 } + +{ + + "ErrorCode":"Код ответа", + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 5/16 + + + +3. Нотификация ТСП о финальном статусе оплаты по динамическому QR-коду + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н + +Метод «qrc/notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1...50) y Тип запроса. Константа «qrc/notification» + +qrcId String (an-32) y Идентификатор QR-кода. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +status String (an-10) y Статус оплаты QR-кода в НСПК. + +Возможные значения: + +— ACWP — ACCEPTED операция завершена успешно; + +— RJCT — REJECTED операция отклонена. + +amount Number y Сумма платежа в минорных единицах (копейках) + +timestamp YYYY-MMDDThh: mm: ss[.SSS] + +или + +YYYY-MMDDThh: mm: ss[.SSSZ] + +y Метка времени НСПК по Гринвичу (GMT). + +payerId String (n-13) y Идентификатор плательщика (маскированный номер те + +kzo String (ans 1-128) o Контрольное Значение Операции СБП. + +Формируется ОПКЦ СБП. Присутствует при условии, чт + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка + +TermNo String (an-20) Y Уникальный идентификатор терминала. + +CreditDatePos String (ans 1-256) o Дата операции, установленная Банком Получателя в хо + +b) Примерный формат запроса: + +c) ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Агента ТСП. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система, принимающая их от шлюза Альфа-Банка, + + "message":"Расшифровка кода ответа" + +} + +1 { + +2 "command":"qrc/notification", + +3 "qrcId":"AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + +4 "trxId":"A3013090427361010000057B3DA2D4A7", + +5 "status":"ACWP", + +6 "amount":"10000", + +7 "timestamp":"2022-10-27T14:33:49.000Z ", + +8 "payerId":"*********1779", + +9 "kzo":"580d2f38370f378db5915c047ba7b72014327ce455caa927b2488f224926daac85e82984c889d66e79dad8039cc + +10 "payrrn":"000000022154", + +11 "TermNo":"90080567", + +12 "CreditDatePos":"20221027" + +13 } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 6/16 + + + +4. Запрос проведения возврата по успешной оплате по динамическому QR-коду + +Возврат по СБП состоит из 2х последовательных запросов: + +• GetQRCreversalData — проверка возможности проведения возврата; + +• QRCreversal — выполнение непосредственно самого возврата. + +В случае если ТСП инициирует выполнение повторных операций СБП B2C по одной и той же операции СБП C2B, то допускается не б + +Возврат в один этап. При направлении запроса «QRCReversal», с заполненным полем messageID будет произведен возврат в один + +4.1. Запрос возможности проведения возврата + +Запрос GetQRCreversalData направляется ТСП в Банк для проверки возможности возврата по ранее оплаченному QR-коду и получен + +Метод GetQRCreversalData + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCreversalData». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y/o Идентификатор QR-кода (обязательно, если не передан «payrrn» или «trxId»). + +payrrn String (n-12) y/o Референсный идентификатор запроса в системе Банка (обязательно, если не  + +trxId String (an-32) y/o Уникальный идентификатор платежа в НСПК (обязательно, если не передан «q + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма возврата в минорных единицах (копейках). Если сумма возврата не пер + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого значе + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +ReturnRestAmount Boolean o Проверка доступного остатка для совершения возврата. + +Доступные значения: + +— true + +— false + +Примечание: + +• Для поиска оригинальной транзакции обязательным является один из параметров: «qrcId», «payrrn» или «trxId»; + +• Терминалы с подключенным сканером и распознаванием QR-кодов могут получить «qrcId», распарсив строку QR-кода с чека опла + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +1 { + +2 "command":"GetQRCreversalData", + +3 "TermNo":"90080567", + +4 "qrcId":"AS1000670LSS7DN18SJQDNP4B05KLJL2", + +5 "payrrn":"000063441405", + +6 "trxId":"X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +7 "trxDT":"20230313052005", + +8 "amount":"10000", + +9 "currency":"RUB", + +10 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +11 "ReturnRestAmount":true + +12 } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 7/16 + + + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +message String (ans-1024) y Расшифровка кода ответа**. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +payerBnkBIC String (n-9) y БИК банка получателя. + +payerBnkName String (an-50) y Наименование банка получателя + +payerId String (n-13) y Идентификатор получателя (маскированный номер телефона получателя). + +payerPam String (ans 1…140) y PAM получателя + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка + +qrcId String (an-32) y Идентификатор QR-кода + +trxDT String (n-14) y Дата и время платежа по Гринвичу (GMT). + +Формат времени — ГГГГММДДччммсс. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +restAmount Number (с двумя знаками после точки) o Сумма доступного остатка к возврату. + +Если в запросе передано значение "ReturnRestAmount" : true, то в ответе д + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +Примечание: + +• Текстовые данные передаются в формате urlencoded; + +• В случае получения «message»: «Получен отказ на запрос возврата. Статус Recall, ErrDebetMerchant: KSM0284 Invalid special cond + +• 400 Bad Request + +4.2. Запрос возврата оплаты QR-кода + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "message": "OK", + +5 "payerBnkBIC": "044525593", + +6 "payerBnkName": "Альфа-Банк", + +7 "payerId": "*1234", + +8 "payerPam": "ФСИ", + +9 "payrrn": "000063441405", + +10 "qrcId": "AS1000670LSS7DN18SJQDNP4B05KLJL2", + +11 "trxDT": 20200728114531, + +12 "trxId": "X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +13 "restAmount":"99.87" + +14 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 8/16 + + + +Запрос QRCreversal направляется ТСП в Банк для возврата по ранее произведенной оплате QR. Возврат производится только на сче + +Метод QRCreversal + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «QRCreversal». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y/o Идентификатор QR-кода (обязательно, если не передан «payrrn» или «trx + +payrrn String (n-12) y/o Референсный идентификатор запроса в системе Банка (обязательно, есл + +trxId String (an-32) y/o Уникальный идентификатор платежа в НСПК (обязательно, если не перед + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма возврата в минорных единицах (копейках). Если сумма возврата н + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого + +messageID String (an-1…50) y/o Уникальный идентификатор сообщения, GUID из сообщения «GetQRCrev + +queryData.notificationUrl String (ans-512) o Полный URL для получения уведомления о финальном статусе возврата + +ReturnRestAmount Boolean o Проверка доступного остатка для совершения возврата. + +Доступные значения: + +— true + +— false + +Блок для внесения д + +Код ключа Тип данных required + +extJsonParams Object o + +JsonParam1 String (ans-250) o + +JsonParam2 String (ans-250) o + +... ... ... + +JsonParam10 String (ans-250) o + +* messageID — необходимо передавать точное значение, которые было указано в ответе на запрос GetQRCreversalData. Если значени +на возврат. + +** Блок для передачи дополнительных идентификаторов ТСП в ежедневные реестры СБП. Функционал потребует дополнительной + +Примечание: Для поиска оригинальной транзакции обязательным является один из параметров: «qrcId», «payrrn» или «trxId». + +b) Примерный формат запроса: + +1 { + +2 "command":"QRCreversal", + +3 "TermNo":"90080567", + +4 "qrcId":"AS1000670LSS7DN18SJQDNP4B05KLJL2", + +5 "payrrn":"000063441405", + +6 "trxId":"X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +7 "trxDT":"20230313052005", + +8 "amount":"10000", + +9 "currency":"RUB", + +10 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 9/16 + + + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +message String (ans-1024) y Расшифровка кода ответа**. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +trxDT String(n-14) y Дата и время операции возврата (ГГГГММДДччммсс). + +trxId String(an-32) y Уникальный идентификатор операции возврата в НСПК. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +restAmount Number (с двумя знаками после точки) o Сумма доступного остатка к возврату. + +Если в запросе передано значение "ReturnRestAmount" : true, то в ответе дол + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +11 "extJsonParams": + +12 { + +13 "JsonParam1":"Value", + +14 "JsonParam2":"Value", + +15 "JsonParam3":"Value", + +16 "JsonParam4":"Value", + +17 "JsonParam5":"Value", + +18 "JsonParam6":"Value", + +19 "JsonParam7":"Value", + +20 "JsonParam8":"Value", + +21 "JsonParam9":"Value", + +22 "JsonParam10":"Value" + +23 }, + +24 "queryData": + +25 { + +26 "notificationUrl":"http://sbp-refunds/" + +27 }, + +28 "ReturnRestAmount": true + +29 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "currency": "RUB", + +6 "message": "%u0412%u043E%u0437%u0432%u0440%u0430%u0442%20%u043F%u0440%u043E%u0432%u0435%u0434% + +7 "messageID":"message" + +8 "payrrn": "000063441405", + +9 "trxDT": 20230624143642, + +10 "trxId": "A3024113609260070000086B8426B817", + +11 "restAmount": "99.87" + +12 } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 10/16 + + + +5. Запрос статуса возврата СБП (B2C) + +Метод «GetQRCreversalStatus» необходим ТСП для уточнения статуса операции B2C (метод QRCreversal). + +В запросе «GetQRCreversalStatus» обязательно должна быть передана пара параметров: + +1. «payrrn» или «originalTrxId» Один из параметров «payrrn» или «originalTrxId» используется для нахождения исходного платежа C2 + +2. «trxId» или «messageID». Один из параметров «trxId» или «messageID» используется для нахождения операции возврата B2C, по  + +Метод «GetQRCreversalStatus» + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +payrrn String (n-12) y/o + +(обязательно, если не передан параметр «originalTrxId») + +originalTrxId String (an-32) y/o + +(обязательно, если не передан параметр «payrrn») + +trxId String (an-32) y/o + +(обязательно, если не передан messageID,) + +messageID String (ans-1…1024) y/o +(обязательно, если не передан trxId) + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ошибки*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +Url String (ans 1-512) o Полный URL получения уведомления для ТСП — значение параметра, + +amount Number y Сумма Операции СБП в копейках. Целое, положительное число. Валют + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +{ + + "command":"GetQRCreversalStatus", + + "TermNo":"90080567", + + "payrrn":"000063441405", + + "originalTrxId":"X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + + "trxId":"A3024113609260070000086B8426B817", + + "messageID":"message" + +} + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 11/16 + + + +Код ключа Тип данных required Назначение + +message String (ans-1024) y Описание результата выполнения запроса**. + +messageID String (ans-1024) o Значение параметра «messageID» из запроса «QRCreversal». + +originalQrcId String (an-32) y Идентификатор зарегистрированной Платежной ссылки СБП, по которо + +originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B. + +payerId String (an-13) y Маскированный номер телефона Клиента-Получателя (Плательщика в  + +status String (an-4) y Статус операции возврата СБП (B2C): + +ACWP — ACCEPTED операция завершена успешно; + +RJCT — REJECTED операция отклонена; + +NTST — Статус операции неизвестен. + +trxDT String (n-14) y Дата и время выполнения Операции СБП B2C по сценарию «Возврат п + +trxId String (an-32) y Уникальный идентификатор операции возврата в НСПК. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 ОК + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +6. Запрос истории возвратов по определённой транзакции СБП C2B + +Запрос позволяет ТСП проверить все совершённые возвраты по определённой транзакции СБП C2B. + +В ответе на запрос возвращаются как успешные, так и неуспешные попытки возвратов. + +Метод GetQRCreversalHistory + +a) Описание параметров запроса: + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "message": "OK", + +6 "messageID": "message" + +7 "originalQrcId": "AS1000670LSS7DN18SJQDNP4B05KLJL2", + +8 "originalTrxId": "X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +9 "payerId": "*********1234", + +10 "status": "ACWP", + +11 "trxDT": 20230624143642, + +12 "trxId": "A3024113609260070000086B8426B817" + +13 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 12/16 + + + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +payrrn String (n-12) y + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +Refunds Array y Массив объектов, содержащих информацию о возвратах по плат + +При отсутствии возвратов, будет возвращён ответ с сообщением + +refunds.TermNo String (an-20) y Уникальный идентификатор терминала + +refunds.amount Number y Сумма Операции СБП B2C (возврат) в копейках. Целое, положител + +refunds.originalQrcId String (an-32) y Идентификатор зарегистрированной Платёжной ссылки СБП (QR-к + +refunds.originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B в НСПК + +refunds.payerId String (an-15) y Маскированный номер телефона Клиента-Получателя (Плательщи + +refunds.status String (an-4) y Статус операции возврата СБП (B2C): + +1. ACWP — ACCEPTED возврат успешно выполнен + +2. RJCT — REJECTED возврат отклонён + +3. NTST — NOT_STARTED возврат не инициирован (получен успе + +refunds.trxId String (an-32) y Идентификатор Операции возврата СБП B2C по сценарию «Возвра + +refunds.trxDT String (n-4) y Дата и время выполнения Операции возврата СБП B2C по сцена + +Формат: ГГГГММДДччммсс, UTC +0 + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа «ACWP» и «RJCT»: + +• 200 ОК + +{ + + "command":"GetQRCreversalHistory", + + "TermNo":"90080567", + + "payrrn":"000000002212" + +} + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "refunds": [ + +5 { + +6 "TermNo": 90080567, + +7 "amount": 10000, + +8 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 13/16 + + + +• 400 Bad Request + +e) Примерный формат ответа «NTST»: + +• 200 ОК + +• 400 Bad Request + +f) Примерный формат ответа при отсутствии возвратов по транзакции СБП C2B: + +• 200 OK + +Декодирование значения поля «message» - «По данной оплате возвраты не найдены». + +• 400 Bad Request + +9 "originalTrxId": "B51390819586020Z0000120011510503", + +10 "payerId": "*********1234", + +11 "status": "ACWP", + +12 "trxDT": 20250519082345, + +13 "trxId": "B51390823097450W0000180011510503" + +14 }, + +15 { + +16 "TermNo": 90080567, + +17 "amount": 10000, + +18 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +19 "originalTrxId": "B51390819586020Z0000120011510503", + +20 "payerId": "*********1234", + +21 "status": "RJCT", + +22 "trxDT": 20250519083836, + +23 "trxId": "A4327120041167130000020011381101" + +24 } + +25 ] + +26 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "refunds": [ + +5 { + +6 "TermNo": 90080567, + +7 "amount": 10000, + +8 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +9 "originalTrxId": "B51390819586020Z0000120011510503", + +10 "payerId": "*********1234", + +11 "status": "NTST", + +12 "trxId": "B51390835362750D0000100011510503" + +13 } + +14 ] + +15 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +{ + + "ErrorCode": 0, + + "message": "%u041F%u043E%20%u0434%u0430%u043D%u043D%u043E%u0439%20%u043E%u043F%u043B%u0430%u0442 + + } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 14/16 + + + +7. Нотификация о финальном статусе возврата по динамическому QR-коду + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н + +Метод «b2c-refund/notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «b2c-refund/notification» + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID + +TermNo String (an-20) y Уникальный идентификатор терминала + +originalQrcId String (an-32) y Идентификатор зарегистрированной Платежно + +originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B + +trxId String (an-32) y Идентификатор Операции СБП B2C по сценар + +trxDT String (n-14) y Дата и время выполнения Операции СБП B2C  + +status String (an-4) y Финальный статус Операции СБП B2C: + +«ACWP» — ACCEPTED операция завершена у + +«RJCT» — REJECTED операция отклонена; + +amount Number y Сумма операции в копейках + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +payerId String (an-15) y Маскированный номер телефона Клиента-Полу + +agentRefundRequestId String (an-32) y Уникальный идентификатор запроса, назначае + +opkcRefundRequestId String (an-32) y Уникальный идентификатор запроса на возвра + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +b) Примерный формат запроса (по успешному возврату): + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +1 { + +2 "command":"b2c-refund/notification", + +3 "messageID":" message", + +4 "TermNo":"90080567", + +5 "originalQrcId":"AS1000670LSS7DN18SJQDNP4B05KLJL2", + +6 "originalTrxId":"X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +7 "trxId":" A3024113609260070000086B8426B817", + +8 "trxDT":"20230624143642", + +9 "status":"ACWP", + +10 "amount":"10000", + +11 "ErrorCode":"0", + +12 "message":"OK", + +13 "payerId":"*********1234", + +14 "agentRefundRequestId":"00000000000000000182_abcd1994383", + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 15/16 + + + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено); + +• http-код «500» — Внутренняя ошибка. + +c) Примерный формат запроса (по отклоненному возврату): + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено); + +• http-код «500» — Внутренняя ошибка. + +d) ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Агента ТСП. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система, принимающая их от шлюза Альфа-Банка, + +15 "opkcRefundRequestId":"BR10000OKEISOIPM8ST8TBLQHIN9R185" + +16 } + +1 { + +2 "command":"b2c-refund/notification", + +3 "TermNo":"90080567", + +4 "originalQrcId":"AS1000670LSS7DN18SJQDNP4B05KLJL2", + +5 "originalTrxId":"X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + +6 "trxId":"A3024113609260070000086B8426B817", + +7 "trxDT":"20230624143642", + +8 "status":"RJCT", + +9 "amount":"10000", + +10 "ErrorCode":"0", + +11 "message":"OK", + +12 "payerId":"*********1234" + +13 } + +12/23/25, 11:23 AM Динамический QR-код + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1 16/16 + + diff --git a/_docs/alfabank/qr_payout/5_cache_payment_link_SBP.md b/_docs/alfabank/qr_payout/5_cache_payment_link_SBP.md new file mode 100644 index 0000000..1e3bfdd --- /dev/null +++ b/_docs/alfabank/qr_payout/5_cache_payment_link_SBP.md @@ -0,0 +1,2428 @@ +Кассовая платёжная ссылка + +Кассовая платёжная ссылка СБП + +Кассовая платёжная ссылка — это гибридное решение, которое объединяет в себе преимущества статического и динамического QR- + +Благодаря данному решению сам QR-код не меняется, но в то же время сумма оплаты передаётся с кассы, плательщик не может её и + +Для совершения оплаты по кассовой платёжной ссылке достаточно один раз распечатать QR-код и разместить его в удобной прикас +покупки перед оплатой. + +Для каждой кассы/терминала создается своя кассовая платёжная ссылка. + +При каждой активации кассовой платёжной ссылки передаются значения параметров, соответствующие очередной покупке. + +1. Запрос на регистрацию Кассовой платёжной ссылки СБП + +Данный метод позволяет сгенерировать кассовую платёжную ссылку, которую в дальнейшем ТСП может распечатать в необходимо + +Кроме того, метод предоставляет возможность привязывать, полученные от Банка NFC-таблички, к нужным кассам/терминалам. + +Метод RegCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «RegCashQRc». + +TermNo String (an-20) y Уникальный идентификатор терминала + +mediaType String o Тип картинки QR-кода + +width String o Ширина картинка QR-кода + +height String o Высота картинка QR-кода + +redirectUrl String (ans-1024) о Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. Допускаю + +Если все же требуется использовать в redirectUrl кириллические символы, необходимо пе + +qrcId String (an-32) o Идентификатор QR-кода. Используется в случае, если необходимо привязать заранее зар + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назн + +ErrorCode String (an-20) y Код от + +TermNo String (an-20) y Уникал + +content String y Base6 + +{ + + "command":"RegCashQRc", + + "TermNo":"90080567", + + "mediaType":"image/png", + + "width":"600", + + "height":"600", + + "redirectUrl": "https://exampletsp.io/qwertyui" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 1/28 + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 + + +Код ключа Тип данных required Назн + +mediaType String y Тип ка + +message String (ans-1024) y Расши + +payload String (1…999) y Плате + +qrcId String (an-32) y Идент + +status String (an-20) y Статус + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +• https://qr.nspk.ru/BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9; + +• https://qr.nspk.ru/BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9?type=01&bank=100000000008&crc=2557 + +d) Примерный формат ответа: + +• 200 ОК + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +2. Запрос на активацию Кассовой платёжной ссылки СБП + +Запрос ActivateCashQRc направляется кассой/терминалом ТСП в Банк для активации Кассовой ссылки в целях ожидания оплаты пла + +Метод ActivateCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1… + +50) + +y Тип запроса. Константа «ActivateCashQRc». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String (an-32) y Идентификатор QR-кода. + +amount Number y Сумма платежа в минорных единицах (копейках). + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "content": "iVBORw0KGgoAAAANSUhEUgVXne/ /B2Pwbvw1OqlrAAAAAElFTk…………………………....SuQmCC", + + "mediaType": "image/png", + + "message": "OK", + + "payload": "https://qr.nspk.ru/BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "CREATED" + +} + +{ + +"ErrorCode":"Код ответа", + +"message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 2/28 + +https://qr.nspk.ru/BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9 +https://qr.nspk.ru/BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9?type=01&bank=100000000008&crc=2557 + + +Код ключа Тип данных required Назначение + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). Необязательный параметр, при отсутствии его з + +OrderNumber String (ans- + +1000) + +o Номер заказа. + +В параметре должны передаваться только английские буквы и/или арабские цифры, подчеркивание + +paymentPurpose String (ans- + +140) + +o Назначение платежа. + +queryData.notificationUrl String (ans- + +512) + +o Полный URL для получения уведомления о финальном статусе оплаты QR-кода + +Если параметр отсутствует, уведомление не производится. + +qrTtl String (an-1… + +2) + +o Период использования Кассовой ссылки в минутах. Необязательное поле. + +Допустимый диапазон: 5-20. + +Если поле «qrTtl» не передано, то за период использования Кассовой ссылки берется значение по ум + +redirectUrl String (ans- + +1024) + +o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. Допускаются только + +перекодировать их в соответствующий ASCII код, используя percent-encoded octets согласно RFC398 + +Блок для внесения д + +Код ключа Тип данных required + +extJsonParams Object o + +JsonParam1 String (ans-250) o + +JsonParam2 String (ans-250) o + +... ... ... + +JsonParam10 String (ans-250) o + +* Блок для передачи дополнительных идентификаторов ТСП в ежедневные реестры СБП. Функционал потребует дополнительной н + +b) Примерный формат запроса: + +1 { + +2 "command":"ActivateCashQRc", + +3 "TermNo":"90080567", + +4 "qrTtl":"5", + +5 "amount":"10000", + +6 "currency":"RUB", + +7 "paymentPurpose":"Назаначение платежа", + +8 "OrderNumber":"FYI123456", + +9 "redirectUrl": "https://alfabank.ru/sme/payservice/sbp/", + +10 "extJsonParams": + +11 { + +12 "JsonParam1":"Value", + +13 "JsonParam2":"Value", + +14 "JsonParam3":"Value", + +15 "JsonParam4":"Value", + +16 "JsonParam5":"Value", + +17 "JsonParam6":"Value", + +18 "JsonParam7":"Value", + +19 "JsonParam8":"Value", + +20 "JsonParam9":"Value", + +21 "JsonParam10":"Value" + +22 }, + +23 "queryData": + +24 { + +25 "notificationUrl":"https://sbp-payments", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 3/28 + + + +c) Описание параметров ответа: + +Код ключа Тип данных + +ErrorCode String (an-20) + +TermNo String (an-20) + +amount Number + +currency String (ans-3) + +message String (ans-1024) + +paramsId String + +paymentPurpose String (ans-140) + +payrrn String (an-12) + +qrcId String (an-32) + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 ОК + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +Примечание: + +• При повторной активации прежние значения параметров Кассовой ссылки СБП заменяются на новые; + +• Если Плательщик отсканирует QR-код активированной Кассовой ссылки СБП и перейдёт в Приложение Плательщика и при этом К +совершить оплату; + +• Если в запросе на активацию Кассовой ссылки СБП не будет передан параметр «amount», то ответ вернется с ошибкой — " RQ05019 + +• Если при активации Кассовой ссылки СБП значение периода использования выходит за пределы допустимого диапазона 1-20 мин +значение периода использования Кассовой ссылки СБП — 1 минута, максимальное — 20. + +• Если оплата с использованием Кассовой ссылки СБП имеет финальный статус RJCT (оплата не прошла), то ТСП может повторно а + +26 } + +27 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "currency": "RUB", + +6 "message": "OK", + +7 "paramsId": "BP10001UMBREG8GI9AFRVAD7S7GJEK6E", + +8 "paymentPurpose": "%u041D%u0430%u0437%u043D%u0430%u0447%u0435%u043D%u0438%u0435 %u043F%u043B%u + +9 "payrrn": "000056251465", + +10 "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" + +11 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 4/28 + + + +• Оплата с использованием Кассовой ссылки СБП невозможна, если: +а) истек период использования активированной Кассовой ссылки СБП; +б) кассовая ссылка СБП не была активирована вовсе или была деактивирована и не активирована вновь; +в) оплата по ней уже происходит, при этом для очередной оплаты она не была активирована вновь. + +3. Запрос деактивации Кассовой платёжной ссылки СБП + +Запрос DelCashQRc направляется кассой/терминалом ТСП в Банк для досрочной деактивации Кассовой ссылки. + +Если Плательщик решил отказаться от покупки и не намерен совершать оплату, когда кассовая ссылка уже была активирована, то о +процедура оплаты. Деактивация Кассовой ссылки СБП влечет за собой отмену всех дальнейших действий для оплаты по активиров + +Если кассовая ссылка была активирована, и по ней происходит оплата, то в ответе на запрос «Деактивация Кассовой ссылки СБП» ве + +Метод DelCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-10) y + +qrcId String(an-32) y + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +message String (ans-140) y + +TermNo String (an-10) y + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +{ + + "command":"DelCashQRc", + + "TermNo":"90080567", + + "qrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" + +} + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "message": "%u0417%u0430%u043F%u0440%u043E%u0441 %u043E%u0431%u0440%u0430%u0431%u043E%u0442%u043 + + } + +{ + + "ErrorCode":"Код ответа", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 5/28 + + + +4. Запрос статуса Кассовой платёжной ссылки СБП + +• Направляется ТСП в Банк для проверки статуса ранее зарегистрированной кассовой ссылки, например, в целях проверки готовно + +• Может быть направлен для проверки статуса после попытки активации, в случае, если на запрос активации не получен ответ от Н + +• Успешный ответ содержит статус самой Кассовой ссылки, но не операции ее оплаты. + +Метод GetCashQRCstatus + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +qrcId String (an-32) y + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных + +ErrorCode String (an-20) + +message String (ans-140) + +status String + +paramsId String (an-32) + +merchantId String (12) + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + + "message":"Расшифровка кода ответа" + + } + +{ + + "command": "GetCashQRCstatus", + + "TermNo": "90080567", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" + +} + +{ + + "ErrorCode": 0, + + "merchantId":"MB0000009603", + + "message":"Запрос обработан успешно", + + "qrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "WAITING_PAYMENT", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 6/28 + + + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +5. Запрос изменения параметров для зарегистрированной Кассовой платёжной ссылки СБП + +Запрос позволяет изменить следующие параметры Кассовой ссылки СБП: + +• Номер счёта юридического лица — «account» + +• Номер терминала — «TermNo» + +• Торгово-сервисную точку (ТСТ) — «merchantId» + +• Ссылку для автоматического возврата в приложение или на сайт ТСП — «redirectUrl» + +Смена счёта юридического лица + +Метод ChangeAccForCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «ChangeAccForC + +TermNo String (an-20) y Уникальный идентификатор терминала, + +qrcId String (an-32) y Идентификатор Кассовой ссылки СБП + +account String (n-32) y Новый счёт юридического лица + +b) Примерный формат запроса для смены номера счёта Кассовой ссылки СБП: + +c) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +message String (ans-1024) y + + "paramsId": "BP10001UMBREG8GI9AFRVAD7S7GJEK6E" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +{ + + "command":"ChangeAccForCashQRc", + + "TermNo":"90080567", + + "qrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "account":"00000000000000001111" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 7/28 + + + +Код ключа Тип данных required + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +Смена номера терминала/мерчанта для Кассовой ссылки СБП + +При успешном выполнении запроса Кассовая ссылка СБП будет перенесена на новый терминал/мерчант + +Метод ChangeAccForCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «ChangeAccForCashQRc» + +TermNo String (an-20) y Уникальный идентификатор терминала, на который Кассовая с + +qrcId String (an-32) y Идентификатор QR-кода + +account String (n-32) y Счёт юридического лица, установленный для нового терминал + +NewTermNo String (an-20) y Новый уникальный идентификатор терминала + +NewMerchantId String (an-12) y/o Идентификатор новой ТСТ. + +Поле обязательно, если терминал, на который переносится + +b) Примерный формат запроса для переноса КС на новый терминал, зарегистрированный в рамках одной ТСТ: + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "account": "00000000000000001111", + + "merchantId": " MA0001111111", + + "message": "OK", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "UPDATED" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +{ + + "command":"ChangeAccForCashQRc", + + "TermNo":"90080567", + + "account":"00000000000000001111", + + "qrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "NewTermNo":"90011111" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 8/28 + + + +c) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +message String (ans-1024) y + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +e) Примерный формат запроса для переноса КС на новый терминал, зарегистрированный в другой ТСТ или в другом юридическом + +f) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +{ + + "ErrorCode": 0, + + "TermNo": 90011111, + + "account": "00000000000000001111", + + "merchantId": " MA0001111111", + + "message": "OK", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "UPDATED" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +{ + + "command": "ChangeAccForCashQRc", + + "TermNo": "90080567", + + "account": "00000000000000002222", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "NewTermNo": "90022222", + + "NewMerchantId": "MA0002222222" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 9/28 + + + +Код ключа Тип данных required + +message String (ans-1024) y + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +g) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +h) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +message String (ans-1024) y + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +Перенос кассовой ссылки на нового мерчанта со старым номером терминала + +При успешном выполнении запроса Кассовая ссылка СБП будет перенесена на нового мерчанта вместе со старым терминало + +Метод ChangeAccForCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «ChangeAccForC + +TermNo String (an-20) y Уникальный идентификатор терминала, + +{ + + "ErrorCode": 0, + + "TermNo": 90022222, + + "account": "00000000000000002222", + + "merchantId": " MA0002222222", + + "message": "OK", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "UPDATED" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 10/28 + + + +Код ключа Тип данных required Назначение + +qrcId String (an-32) y Идентификатор QR-кода + +account String (n-32) y Счёт юридического лица, используемый + +NewMerchantId String (an-12) y Идентификатор новой ТСТ + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +message String (ans-1024) y + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +Смена ссылки для автоматического возврата в приложение или на сайт ТСП + +При успешном выполнении запроса будет изменено значение поля «redirectUrl», указанное при первоначальной регистрации К + +{ + + "command": "ChangeAccForCashQRc", + + "TermNo": "90080567", + + "account": "00000000000000002222", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "NewMerchantId": "MA0002222222" + +} + +{ + +"ErrorCode": 0, + +"TermNo": 90080567, + +"account": "00000000000000002222", + +"merchantId": " MA0002222222", + +"message": "OK", + +"qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +"status": "UPDATED" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 11/28 + + + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «ChangeAccForCashQRc». + +TermNo String (an-20) y Уникальный идентификатор терминала, на который кассовая ссылка/NFC-табличка была + +qrcId String (an-32) y Идентификатор QR-кода + +redirectUrl String (ans-1024) y Новая ссылка для автоматического возврата в приложение или на сайт ТСП. + +Допускаются только символы в кодировке ASCII. Формат должен соответствовать пра + +Если требуется использовать в redirectUrl кириллические символы, необходимо перек + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required + +ErrorCode String (an-20) y + +TermNo String (an-20) y + +account String (an-20) y + +merchantId String (an-12) y + +message String (ans-1024) y + +qrcId String(an-32) y + +status String (an-4) o + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +{ + + "command": "ChangeAccForCashQRc", + + "TermNo": "90080567", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "redirectUrl": " https://alfabank.ru/sme/payservice/sbp/" + +} + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "account": "00000000000000002222", + + "merchantId": " MA0002222222", + + "message": "OK", + + "qrcId": " BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + + "status": "UPDATED" + +} + +{ + + "ErrorCode":"Код ответа", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 12/28 + + + +6. Запрос на изменение номера терминала (TermNo) для зарегистрированной Кассовой платё + +Данный запрос позволяет ТСП произвести смену номера терминала по ранее зарегистрированной Кассовой ссылке СБП на любой д +может быть использован и для перепривязки кассовой ссылки на новое ЮЛ, ИП. + +Метод ChangeTermNoForCashQRc + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +qrcId String (an-32) y + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +TermNo String (an-20) y Уникальный идентификатор терми + +message String (ans-140) y Расшифровка кода ответа** + +status String (an-4) y Статус выполнения перерегистрац + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + + "message":"Расшифровка кода ответа" + +} + +{ + + "command": "ChangeTermNoForCashQRc", + + "TermNo": "90080567", + + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" + +} + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "message": "OK", + + "status": "UPDATED" + +} + +{ + + "ErrorCode": "Код ответа", + + "message": "Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 13/28 + + + +7. Запрос статуса оплаты по Кассовой платёжной ссылке СБП + +Запрос статуса GetQRCstatus направляется кассой/терминалом ТСП в Банк для получения статуса Операции оплаты выпущенного ра + +Запрос статуса направляется не ранее, чем через 10 секунд после формирования QR-кода и не чаще чем каждые 3 секунды. + +Успешный ответ на запрос статуса можно получить в течении 30 дней после совершения оплаты по данному QR-коду. + +В случае, если срок хранения данных истек, то в ответе на запрос вернется: + +Метод GetQRCstatus + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCstatus». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +payrrn String (n-12) y/o Референсный идентификатор запроса в системе Банка. + +qrcId String (an-32) y/o Идентификатор QR-кода (обязательно, если не передан «pa + +paramsId String (an-32) y/o Идентификатор параметров ссылки СБП (если передан qrcId + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латин + +Примечание: для кассовой платежной ссылки должен быть передан один из параметров: payrrn или qrcId + paramsId. Передавать в з + +b) Примерный формат запроса: + +1-й вариант запроса: + +2-й вариант запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +message String (ans-1024) y Расшифровка кода ответа**. + +{ + +"ErrorCode":999, + +"message":"Неизвестный код проблемы 999RQ05014" + +} + +{ + + "command":"GetQRCstatus", + + "TermNo":"90080567", + + "payrrn":"000056251465", + + "messageID":"message" + +} + +{ + + "command":"GetQRCstatus", + + "TermNo":"90080567", + + "qrcId": "AS1R005G9DAOLK5L8S5OPR6HB23HSN0I", + + "paramsId": "BP10001UMBREG8GI9AFRVAD7S7GJEK6E", + + "messageID":"message" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 14/28 + + + +Код ключа Тип данных required Назначение + +qrcId String (an-32) y Идентификатор QR-кода. + +status String(an-10) y Статус оплаты QR-кода в НСПК* + +Возможные значения: + +1. ACWP — ACCEPTED операция завершена успешно; + +2. RJCT — REJECTED операция отклонена; + +3. NTST — NOT_STARTED операции по QR коду не существует; + +4. RCVD — RECEIVED операция в обработке. + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК. + +trxDT String (n-14) y Дата и время платежа по Гринвичу. + +Формат — ГГГГММДДччммсс. + +payrrn String (n-12) o Референсный идентификатор запроса в системе Банка. Значение возвращается если зап + +CreditDatePos String (ans 1-256) o Дата операции, установленная Банком Получателя (ГГГГММДД) + +TermNo String (an-20) y Уникальный идентификатор терминала. + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). + +Url String (ans 1-512) o Полный URL для получения уведомления ТСП о финальном статусе оплаты QR-кода. Зн + +paramsId String (an-32) o Идентификатор активных значений параметров Платежной ссылки СБП. Передается, есл + +payerId String (ans) y Идентификатор плательщика (маскированный номер телефона плательщика). + +Kzo String (ans 1-128) o Контрольное Значение Операции СБП. Формируется ОПКЦ СБП. + +Присутствует при условии, что Операция СБП C2B по запрашиваемому qrcId завершена + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. + +Значение параметра возвращается в случае, если оно указано в запросе. + +merchantId String (12) o ID мерчанта (ТСТ) в Банке + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +Примечание: + +• Успешно оплаченным считается только QR-код, для которого получен «status» = «ACWP» с идентификатором платежа «trxId» и «E + +• В случае если получен «status» = «NTST» — означает необходимость повтора запроса до получения одного из финальных статусов + +• Получение «status» = «RJCT» означает отказ в оплате данного QR-кода. + +d) Примерный формат ответа: + +• 200 OK + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +5 "status": "ACWP", + +6 "trxId": "A30180803159571F0000097B3DA2D4A7", + +7 "trxDT": "20230118080315", + +8 "payrrn": "000056251465", + +9 "CreditDatePos": "20230118", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 15/28 + + + +Примечание: + +• Текстовые данные передаются в формате urlencoded. + +• В поле " trxDT» содержится дата и время транзакции на ПШ Банка в формате ГГГГММДДччммсс. + +В случае получения значения trxId = null необходимо повторить запрос. Отсутствие значения означает, что в СБП еще нет успешного + +• 400 Bad Request + +8. Нотификация ТСП о финальном статусе оплаты по Кассовой платёжной ссылке СБП + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н + +Метод «qrc/notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «qrc/notification» + +qrcId String (an-32) y Идентификатор QR-кода. + +trxId String(an-32) y Уникальный идентификатор платежа в Н + +paramsId String (an-32) y Идентификатор активных значений пара + +status String(an-10) y Статус оплаты QR-кода в НСПК. + +Возможные значения: + +— ACWP — ACCEPTED операция заверш + +— RJCT — REJECTED операция отклоне + +amount Number y Сумма платежа в минорных единицах (ко + +timestamp YYYY-MMDDThh: mm: ss[.SSS] + +или + +YYYY-MMDDThh: mm: ss[.SSSZ] + +y Метка времени НСПК по Гринвичу (GMT) + +payerId String (ans) y Идентификатор плательщика (маскирова + +kzo String (ans 1-128) o Контрольное Значение Операции СБП. Ф + +Присутствует при условии, что Операция + +payrrn String (n-12) y Референсный идентификатор запроса в  + +TermNo String (an-20) y Уникальный идентификатор терминала + +10 "TermNo": 90080567, + +11 "amount": 10000, + +12 "currency": "RUB", + +13 "Url":"https://sbp-payments", + +14 "paramsId": "BP10001UMBREG8GI9AFRVAD7S7GJEK6E", + +15 "payerId": "*********1234", + +16 "kzo": "b02bf0fb819dcc6249f1f6be81da28062236febcb25774a29ebdd770f2a35ba29fa038e459c0845ade1ef2 + +17 "messageID ":"message" + +18 "merchantId": "MB0000009603" + +19 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 16/28 + + + +Код ключа Тип данных required Назначение + +CreditDatePos String (ans 1-256) o Дата операции, установленная Банком П + +b) Примерный формат запроса: + +c) ВС отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Агента ТСП. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система принимающая их от шлюза Альфа-Банка + +9. Запрос операций по Кассовой платёжной ссылке СБП + +• Запрос позволяет выполнить поиск всех операций оплаты и возвратов, произведенных по определенной кассовой платежной ссы + +• В ответе платежный шлюз Банка возвращает результат обработки запроса с разбивкой по массивам payments (оплаты) и refunds (в + +Метод «GetCashQrcId» + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +qrcId String (an-32) y + +dateFrom date-time y + +dateTo date-time y + +Примечание: Временной диапазон dateFrom — dateTo не должен быть более семи календарных дней. Время в параметре dateFrom д + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +1 { + +2 "command":"qrc/notification", + +3 "qrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +4 "trxId":"A30180803159571F0000097B3DA2D4A7", + +5 "paramsId":"BP10001UMBREG8GI9AFRVAD7S7GJEK6E", + +6 "status":"ACWP", + +7 "amount":"10000", + +8 "timestamp":"2023-02-07T08:35:31.102Z", + +9 "payerId":"*********1234", + +10 "kzo":"d4d45d9db80b29fec2aacbfaf778edc49ff615c13021a2bf5a05f35d8afbcc76f84ceda7598695956c1d5168b1f + +11 "payrrn":"000056251465", + +12 "TermNo":"90080567", + +13 "CreditDatePos":"20230207" + +14 } + +{ + + "command": "GetCashQrcId", + + "TermNo": "90080567", + + "qrcId": "BS10005FR8SV6EI9931BIQGPSUEG8ELL", + + "dateFrom": "2023-03-12T17:30:09", + + "dateTo": "2023-03-12T23:25:15" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 17/28 + + + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный + +payments array o **Массив пла + +operationId string y id платежа в  + +status string (enum) y Статус оплат + +— SUCCESS, + +— REJECTED + +reason string o Описание со + +amount number y Сумма в коп + +date date-time y Формат YYY + +refunds array o **Массив воз + +refundId string y id возврата в + +date date-time y Формат YYY + +status string (enum) y Статус возвр + +— SUCCESS, + +REJECTED, + +reason string o Описание пр + +amount number y Сумма в коп + +* Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "payments": [ + +5 { + +6 "amount": 10000, + +7 "date": "2024-02-07T14:08:13", + +8 "operationId": "A4038110812414010000020011180902", + +9 "reason": "Запрос обработан успешно", + +10 "status": "SUCCESS" + +11 } + +12 ], + +13 "refunds": [ + +14 { + +15 "amount": 10000, + +16 "date": "2024-02-07T14:19:36", + +17 "reason": "Платёж проведён", + +18 "refundId": "A4038111858413010000020011180902", + +19 "status": "SUCCESS" + +20 } + +21 ] + +22 } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 18/28 + + + +e) При проверке обязательности заполнения параметров запроса, в случае, если какой-либо параметр не заполнен в ответе вернуть + +ErrorCode message + +"3" Не передан обязательный параметр dateFrom/dateTo + +"16" Не передан параметр TermNo + +"41" Не передан параметр qrcId + +"301" Превышен временной диапазон dateFrom-dateTo + +10. Запрос проведения возврата по успешной оплате по Кассовой платёжной ссылке СБП + +Возврат по СБП состоит из 2х последовательных запросов: + +• GetQRCreversalData — проверка возможности проведения возврата; + +• QRCreversal — выполнение непосредственно самого возврата. + +В случае если ТСП инициирует выполнение повторных операций СБП B2C по одной и той же операции СБП C2B, то допускается не б + +Возврат в один этап. При направлении запроса «QRCReversal», с заполненным полем messageID будет произведен возврат в один + +10.1. Запрос возможности проведения возврата + +Запрос GetQRCreversalData направляется ТСП в Банк для проверки возможности возврата по ранее оплаченному QR-коду и получен + +Метод GetQRCreversalData + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCreversalData». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +payrrn String (n-12) y/o Референсный идентификатор запроса в системе Банка (обязательно, если не  + +trxId String (an-32) y/o Уникальный идентификатор платежа в НСПК (обязательно, если не передан «p + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма возврата в минорных единицах (копейках). Если сумма возврата не пер + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого значе + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +ReturnRestAmount Boolean o Проверка доступного остатка для совершения возврата. + +Доступные значения: + +— true + +— false + +Примечание: + +• Для поиска оригинальной транзакции обязательным является один из параметров: «payrrn» или «trxId»; + +• Терминалы с подключенным сканером и распознаванием QR-кодов могут получить «qrcId», распарсив строку QR-кода с чека опла + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 19/28 + + + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +message String (ans-140) y Расшифровка кода ответа**. + +messageID String (an-1…50) y/o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +payerBnkBIC String (n-9) y БИК банка получателя + +payerBnkName String (an-50) y Наименование банка получателя + +payerId String (n-13) y Идентификатор получателя (маскированный номер телефона получателя). + +payerPam String (ans 1…140) y PAM получателя + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка + +qrcId String(an-32) y Идентификатор QR-кода. + +trxDT String (n-14) y Дата и время платежа в AnyWay (ГГГГММДДччммсс) + +trxId String (an-32) y Уникальный идентификатор платежа в НСПК + +restAmount Number (с двумя знаками после точки) o Сумма доступного остатка к возврату. + +Если в запросе передано значение "ReturnRestAmount" : true, то в ответе д + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +1 { + +2 "command":"GetQRCreversalData", + +3 "TermNo":"90080567", + +4 "payrrn":"000056251465", + +5 "trxId": "A30180803159571F0000097B3DA2D4A7", + +6 "trxDT":"20230416082214", + +7 "amount":"10000", + +8 "currency":"RUB", + +9 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +10 "ReturnRestAmount": true + +11 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "message": "OK", + +5 "messageID":"message", + +6 "payerBnkBIC": "044525225", + +7 "payerBnkName": "Альфа-Банк", + +8 "payerId": "*1234", + +9 "payerPam": "ИИИ", + +10 "payrrn": "000056251465", + +11 "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +12 "trxDT": 20230118124954, + +13 "trxId": "A3018124954175080000087B3DA2D4A7", + +14 "restAmount":"99.87" + +15 } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 20/28 + + + +Примечание: + +• Текстовые данные передаются в формате urlencoded; + +• В случае получения "message»: «Получен отказ на запрос возврата. Статус Recall, ErrDebetMerchant: KSM0284 Invalid special cond + +• 400 Bad Request + +10.2. Запрос возврата оплаты + +Запрос QRCreversal направляется ТСП в Банк для возврата по ранее произведенной оплате QR. Возврат производится только на сче + +Метод QRCreversal. + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «QRCreversal». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +payrrn String (n-12) y/o Референсный идентификатор запроса в системе Банка (обязательно, есл + +trxId String (an-32) y/o Уникальный идентификатор платежа в НСПК (обязательно, если не перед + +trxDT String (n-14) o Дата и время отменяемого платежа. + +amount Number o Сумма возврата в минорных единицах (копейках). Если сумма возврата н + +currency String (ans-3) o Код валюты (для рублей должен передаваться «RUB»). В случае пустого + +messageID String (an-1…50) y/o Уникальный идентификатор сообщения, GUID из сообщения «GetQRCrev + +queryData.notificationUrl String (ans-512) o Полный URL для получения уведомления о финальном статусе возврата + +ReturnRestAmount Boolean o Проверка доступного остатка для совершения возврата. + +Доступные значения: + +— true + +— false + +Блок для внесения д + +Код ключа Тип данных required + +extJsonParams Object o + +JsonParam1 String (ans-250) o + +JsonParam2 String (ans-250) o + +... ... ... + +JsonParam10 String (ans-250) o + +* messageID — необходимо передавать точное значение, которые было указано в ответе на запрос GetQRCreversalData. Если значени +на возврат. + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 21/28 + + + +** Блок для передачи дополнительных идентификаторов ТСП в ежедневные реестры СБП. Функционал потребует дополнительной + +Примечание: Для поиска оригинальной транзакции обязательным является один из параметров: «payrrn» или «trxId». + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +message String (ans-1024) y Расшифровка кода ответа**. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +trxDT String(n-14) y Дата и время операции возврата (ГГГГММДДччммсс). + +trxId String(an-32) y Уникальный идентификатор операции возврата в НСПК. + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +restAmount Number (с двумя знаками после точки) o Сумма доступного остатка к возврату. + +Если в запросе передано значение "ReturnRestAmount" : true, то в ответе дол + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +1 { + +2 "command":"QRCreversal", + +3 "TermNo":"90080567", + +4 "payrrn":"000056251465", + +5 "trxId":"A30180803159571F0000097B3DA2D4A7", + +6 "trxDT":"20230416082214", + +7 "amount":"10000", + +8 "currency":"RUB", + +9 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +10 "extJsonParams": + +11 { + +12 "JsonParam1":"Value", + +13 "JsonParam2":"Value", + +14 "JsonParam3":"Value", + +15 "JsonParam4":"Value", + +16 "JsonParam5":"Value", + +17 "JsonParam6":"Value", + +18 "JsonParam7":"Value", + +19 "JsonParam8":"Value", + +20 "JsonParam9":"Value", + +21 "JsonParam10":"Value" + +22 }, + +23 "queryData": + +24 { + +25 "notificationUrl":"http://sbp-refunds/" + +26 }, + +27 "ReturnRestAmount": true + +28 } + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 22/28 + + + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +11. Запрос статуса возврата СБП (B2C) + +Метод «GetQRCreversalStatus» необходим ТСП для уточнения статуса операции B2C (метод QRCreversal). + +В запросе «GetQRCreversalStatus» обязательно должна быть передана пара параметров: + +1. «payrrn» или «originalTrxId» Один из параметров «payrrn» или «originalTrxId» используется для нахождения исходного платежа C2 + +2. «trxId» или «messageID». Один из параметров «trxId» или «messageID» используется для нахождения операции возврата B2C, по  + +Метод «GetQRCreversalStatus» + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +payrrn String (n-12) y/o + +(обязательно, если не передан параметр «originalTrxId») + +originalTrxId String (an-32) y/o + +(обязательно, если не передан параметр «payrrn») + +trxId String (an-32) y/o + +(обязательно, если не передан messageID,) + +messageID String (ans-1…1024) y/o +(обязательно, если не передан trxId) + +b) Примерный формат запроса: + +4 "amount": 10000, + +5 "currency": "RUB", + +6 "message": "%u0421%u0442%u0430%u0442%u0443%u0441%20%u0432%u044B%u044F%u0441%u043D%u0435%u043D% + +7 "messageID":"message" + +8 "payrrn": "000056251465", + +9 "trxDT": 20230614061308, + +10 "trxId": "B3018130524291090000167B3DA2D4A7", + +11 "restAmount": "99.87" + +12 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +{ + + "command":"GetQRCreversalStatus", + + "TermNo":"90080567", + + "payrrn":"000056251465", + + "originalTrxId":"A30180803159571F0000097B3DA2D4A7", + + "trxId":"B3018130524291090000167B3DA2D4A7", + + "messageID":"message" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 23/28 + + + +c) Примерный формат ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ошибки*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +Url String (ans 1-512) o Полный URL получения уведомления для ТСП — значение параметра, + +amount Number y Сумма Операции СБП в копейках. Целое, положительное число. Валют + +message String (ans-1024) y Описание результата выполнения запроса**. + +messageID String (ans-1024) o Значение параметра «messageID» из запроса «QRCreversal». + +originalQrcId String (an-32) y Идентификатор зарегистрированной Платежной ссылки СБП, по которо + +originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B. + +payerId String (an-13) y Маскированный номер телефона Клиента-Получателя (Плательщика в  + +status String (an-4) y Статус операции возврата СБП (B2C): + +ACWP — ACCEPTED операция завершена успешно; + +RJCT — REJECTED операция отклонена; + +NTST — Статус операции неизвестен. + +trxDT String (n-14) y Дата и время выполнения Операции СБП B2C по сценарию «Возврат п + +trxId String (an-32) y Уникальный идентификатор операции возврата в НСПК. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 ОК + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "amount": 10000, + +5 "message": "OK", + +6 "messageID": "message" + +7 "originalQrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +8 "originalTrxId": "A30180803159571F0000097B3DA2D4A7", + +9 "payerId": "*********1234", + +10 "status": "ACWP", + +11 "trxDT": 20230614061308, + +12 "trxId": "B3018130524291090000167B3DA2D4A7" + +13 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 24/28 + + + +12. Запрос истории возвратов по определённой транзакции СБП C2B + +Запрос позволяет ТСП проверить все совершённые возвраты по определённой транзакции СБП C2B. + +В ответе на запрос возвращаются как успешные, так и неуспешные попытки возвратов. + +Метод GetQRCreversalHistory + +a) Описание параметров запроса: + +Код ключа Тип данных required + +command String (an-1…50) y + +TermNo String (an-20) y + +payrrn String (n-12) y + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +Refunds Array y Массив объектов, содержащих информацию о возвратах по плат + +При отсутствии возвратов, будет возвращён ответ с сообщением + +refunds.TermNo String (an-20) y Уникальный идентификатор терминала + +refunds.amount Number y Сумма Операции СБП B2C (возврат) в копейках. Целое, положител + +refunds.originalQrcId String (an-32) y Идентификатор зарегистрированной Платёжной ссылки СБП (QR-к + +refunds.originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B в НСПК + +refunds.payerId String (an-15) y Маскированный номер телефона Клиента-Получателя (Плательщи + +refunds.status String (an-4) y Статус операции возврата СБП (B2C): + +1. ACWP — ACCEPTED возврат успешно выполнен + +2. RJCT — REJECTED возврат отклонён + +3. NTST — NOT_STARTED возврат не инициирован (получен успе + +refunds.trxId String (an-32) y Идентификатор Операции возврата СБП B2C по сценарию «Возвра + +refunds.trxDT String (n-4) y Дата и время выполнения Операции возврата СБП B2C по сцена + +Формат: ГГГГММДДччммсс, UTC +0 + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа «ACWP» и «RJCT»: + +{ + + "command":"GetQRCreversalHistory", + + "TermNo":"90080567", + + "payrrn":"000000002212" + +} + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 25/28 + + + +• 200 ОК + +• 400 Bad Request + +e) Примерный формат ответа «NTST»: + +• 200 ОК + +• 400 Bad Request + +f) Примерный формат ответа при отсутствии возвратов по транзакции СБП C2B: + +• 200 OK + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "refunds": [ + +5 { + +6 "TermNo": 90080567, + +7 "amount": 10000, + +8 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +9 "originalTrxId": "B51390819586020Z0000120011510503", + +10 "payerId": "*********1234", + +11 "status": "ACWP", + +12 "trxDT": 20250519082345, + +13 "trxId": "B51390823097450W0000180011510503" + +14 }, + +15 { + +16 "TermNo": 90080567, + +17 "amount": 10000, + +18 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +19 "originalTrxId": "B51390819586020Z0000120011510503", + +20 "payerId": "*********1234", + +21 "status": "RJCT", + +22 "trxDT": 20250519083836, + +23 "trxId": "A4327120041167130000020011381101" + +24 } + +25 ] + +26 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +1 { + +2 "ErrorCode": 0, + +3 "message": "OK", + +4 "refunds": [ + +5 { + +6 "TermNo": 90080567, + +7 "amount": 10000, + +8 "originalQrcId": "AS1F004F30VC6B4A9GRBENS0HI6LGRJM", + +9 "originalTrxId": "B51390819586020Z0000120011510503", + +10 "payerId": "*********1234", + +11 "status": "NTST", + +12 "trxId": "B51390835362750D0000100011510503" + +13 } + +14 ] + +15 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 26/28 + + + +Декодирование значения поля «message» - «По данной оплате возвраты не найдены». + +• 400 Bad Request + +13. Нотификация о финальном статусе возврата по Кассовой платёжной ссылке СБП + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н + +Метод «b2c-refund/notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «b2c-refund/notification» + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID + +TermNo String (an-20) y Уникальный идентификатор терминала + +originalQrcId String (an-32) y Идентификатор зарегистрированной Платежно + +originalTrxId String (an-32) y Идентификатор исходной Операции СБП C2B + +trxId String (an-32) y Идентификатор Операции СБП B2C по сценар + +trxDT String (n-14) y Дата и время выполнения Операции СБП B2C  + +status String (an-4) y Финальный статус Операции СБП B2C: + +"ACWP" — ACCEPTED операция завершена ус + +"RJCT" — REJECTED операция отклонена; + +amount Number y Сумма операции в копейках + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +payerId String (an-15) y Маскированный номер телефона Клиента-Полу + +agentRefundRequestId String (an-32) y Уникальный идентификатор запроса, назначае + +opkcRefundRequestId String (an-32) y Уникальный идентификатор запроса на возвра + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +b) Примерный формат запроса (по успешному возврату): + +{ + + "ErrorCode": 0, + + "message": "%u041F%u043E%20%u0434%u0430%u043D%u043D%u043E%u0439%20%u043E%u043F%u043B%u0430%u0442 + + } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +1 { + +2 "command":"b2c-refund/notification", + +3 "messageID":" message", + +4 "TermNo":"90080567", + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 27/28 + + + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено); + +• http-код «500» — Внутренняя ошибка. + +c) Примерный формат запроса (по отклоненному возврату): + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено); + +• http-код «500» — Внутренняя ошибка. + +d) ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Агента ТСП. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система, принимающая их от шлюза Альфа-Банка, + +5 "originalQrcId":"BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +6 "originalTrxId":"A3018124954175080000087B3DA2D4A7", + +7 "trxId":"B3018130524291090000167B3DA2D4A7", + +8 "trxDT":"20230614061308", + +9 "status":"ACWP", + +10 "amount":"10000", + +11 "ErrorCode":"0", + +12 "message":"OK", + +13 "payerId":"*********1234", + +14 "agentRefundRequestId":"00000000000000000182_abcd1994383", + +15 "opkcRefundRequestId":"BR10000OKEISOIPM8ST8TBLQHIN9R185" + +16 } + +1 { + +2 "command":"b2c-refund/notification", + +3 "TermNo":"90080567", + +4 "originalQrcId":" BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + +5 "originalTrxId":" A3018124954175080000087B3DA2D4A7", + +6 "trxId":"A3024113609260070000086B8426B817", + +7 "trxDT":"20230614061308", + +8 "status":"RJCT", + +9 "amount":"10000", + +10 "ErrorCode":"0", + +11 "message":"OK", + +12 "payerId":"*********1234" + +13 } + +12/23/25, 11:24 AM Кассовая платёжная ссылка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1 28/28 + + diff --git a/_docs/alfabank/qr_payout/6_link_account_subscription_SBP.md b/_docs/alfabank/qr_payout/6_link_account_subscription_SBP.md new file mode 100644 index 0000000..110c0ca --- /dev/null +++ b/_docs/alfabank/qr_payout/6_link_account_subscription_SBP.md @@ -0,0 +1,1124 @@ +Привязка счёта/подписка СБП + +Привязка счёта/подписка СБП + +1. Привязка счёта без оплаты (регистрация QR-кода для привязки счёта/подписки по СБП) + +• Запрос «Регистрация QR-кода для привязки счёта/подписки по СБП» позволяет Плательщику выполнить привязку своего банковс +проведения оплаты СБП C2B. + +• Последующие платежи с привязанного счета в адрес данного ТСП в рамках операций СБП C2B будут выполняться без участия Пла + +• Сценарий может применяться как для разовых, так и для регулярных платежей. + +1.1. Метод RegQRcSub + +a) Описание параметров запроса: + +Код ключа Тип +данных required Назначение + +command String (an- + +1…50) + +y Тип запроса. Константа «RegQRcSub». + +TermNo String (an- +20) + +y Уникальный идентификатор терминала. + +qrcType String (an- + +32) + +y Тип запрашиваемого QR-кода. Константа — «03». + +subscriptionPurpose String (ans- + +140) + +y Цель привязки счета. Информация от ТСП с деталями привязки счета. Данная информация будет отобража + +оформлении привязки счета в ДБО Банка Плательщика. Рекомендуется указывать подробную информацию +применимо, регулярность платежей, сумму регулярных платежей и прочее*. + +queryData.notificationUrl String (ans- + +512) + +y Полный URL для получения уведомления о результате привязки счета. + +qrTtl String (an- + +1…6) + +o Срок жизни Функциональной ссылки СБП в минутах. + +Минимальное допустимое значение — «1». Максимальное допустимое значение — «129 600» (90 дней). + +Рекомендация: устанавливать срок жизни Функциональной ссылки СБП не менее «5» минут. Если поле + +будет использовано значение по умолчанию — «4 320» минут (3 суток). + +redirectUrl String (ans- + +1024) + +о Содержит ссылку для автоматического возврата в приложение или на интернет страницу. Допускаются тол + +Формат должен соответствовать правилам кодировки URL. +Если все же требуется использовать в redirectUrl кириллические символы, необходимо перекодировать их в + +используя percent-encoded octets согласно RFC3986. + +Если требуется сформировать QR-код для привязки дополнительного счёта Плательщика в том же Б + +Код ключа Тип +данных required Назначение + +subscriptionServiceId String (32) о Идентификатор привязки. Обязательно при наличии subscriptionServiceName, т. к. параметры subscriptionSe + +могут быть переданы только вместе. При получении параметров subscriptionServiceId и subscriptionServiceN + +использовать их в ходе проверки данных привязки счёта на уникальность. + +subscriptionServiceName String (70) о Наименование привязки. Обязательно при наличии subscriptionServiceId, т. к. параметры subscriptionService + +быть переданы только вместе. При получении параметров subscriptionServiceId и subscriptionServiceName Б + +использовать их в ходе проверки данных привязки счёта на уникальность. + +b) Примерный формат запроса: + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 1/13 + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 + + +Примечание: При отсутствии данных в поле subscriptionPurpose ответ вернется с ошибкой: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +message String (ans-1024) y Расшифровка кода ответа**. + +qrcId String (an-32) y Идентификатор QR-кода. + +payload String (1…999) y Платежная ссылка***. + +payrrn String (an-12) y Референсный идентификатор запроса в системе Банка + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +• https://sub.nspk.ru/AB1S000V3LEOSC2C8HU8H1B06C6P1P5L + +• https://sub.nspk.ru/AB1S000V3LEOSC2C8HU8H1B06C6P1P5L?type=03&bank=100000000008&crc=61C4 + +d) Примерный формат ответа + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +1 { + +2 "command":"RegQRcSub", + +3 "TermNo":"90080567", + +4 "qrTtl":"10", + +5 "qrcType":"03", + +6 "subscriptionPurpose":"Подписка на оплату услуг Интернет 500р./мес.", + +7 "queryData": + +8 { + +9 "notificationUrl":"https://sbp-subscription" + +10 }, + +11 "redirectUrl":"https://exampletsp.io/qwertyui" + +12 } + +{ + + "ErrorCode": 30, + + "message": "Отсутствуют данные в полях: subscriptionPurpose" + +} + +{ + + "ErrorCode":"RQ00000", + + "message":"Запрос обработан успешно", + + "qrcId":"AB1S000V3LEOSC2C8HU8H1B06C6P1P5L ", + + "payload":"https://sub.nspk.ru/AB1S000V3LEOSC2C8HU8H1B06C6P1P5L", + + "payrrn":" 000096116491 " + +} + +{ + + "ErrorCode":"Код ответа", + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 2/13 + +https://sub.nspk.ru/AB1S000V3LEOSC2C8HU8H1B06C6P1P5L +https://sub.nspk.ru/AB1S000V3LEOSC2C8HU8H1B06C6P1P5L?type=03&bank=100000000008&crc=61C4 + + +Результатом выполнения запроса «Регистрация QR-кода для привязки счета/подписки по СБП» является передача Банком Плательщ + +1. «subscriptionToken» — Уникальный Идентификатор привязки счета, назначаемый Банком Плательщика; + +2. «memberId» – Идентификатор банка Плательщика. + +Важно: + +• Значения параметров «subscriptionToken» и «memberId» необходимо хранить в системе ТСП для дальнейшего использования ТСП в +с привязанного счета по инициативе ТСП». В случае отсутствия или утери значения параметра «subscriptionToken», привязку счет +повторно. + +• Для получения значений параметров «subscriptionToken» и «memberId» ТСП необходимо реализовать возможность получения callb + +1.2. Нотификация по сценарию «Регистрация QR-кода для привязки счета/подписки по СБП + +Запрос отправляется из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.notificationUrl» при н +«RegQRcSub». + +Метод «subscription/notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «subscription/notification». + +сode String (an-7) y Возможные варианты кодов ответа: + +— «RQ00000» — Запрос обработан успешно; + +— «RQ05030» — Плательщик отказался от оформления подписки. + +message String (ans-255) y Расшифровка кода ответа*. + +status String (an-10) y Возможные статусы оформления подписки: + +— «ACWP» — подписка оформлена; + +— «RJCT» — подписка не оформлена. + +qrcId String (an-32) y Идентификатор QR-кода + +subscriptionToken String (an-32) o Идентификатор Подписки, назначаемый Банком Плательщика. + +Отсутствует, если Плательщик не дал согласие на оформление подписки. + +memberId String (an-12) o Идентификатор Банка Плательщика. +Отсутствует, если Плательщик не дал согласие на оформление подписки. + +* Таблица возможных кодов ответа приведена в приложении 2. + +b) Примерный формат запроса при согласии Плательщика совершить привязку счёта: + +c) Примерный формат запроса при отказе Плательщика совершить привязку счёта: + + "message":"Расшифровка кода ответа" + +} + +{ + + "command":"subscription/notification ", + + "сode":"RQ00000", + + "message":"Привязка счета оформлена", + + "status":"ACWP", + + "qrcId":"BB1S0053V5S91S2E83RPL8THQSRS7O8K", + + "subscriptionToken":"6feeacc6a74648589285346e3785ad9e", + + "memberId":"100000000008" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 3/13 + + + +d) ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Альфа-Банка. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система принимающая их от шлюза Альфа-Банка +такие неожиданные параметры как ошибочный запрос. + +2. Оплата по QR-коду с последующей привязкой счёта/подпиской по СБП + +• Запрос «Оплата по QR-коду с последующей привязкой/подпиской по СБП» позволяет Плательщику выполнить разовую оплату в р +с последующей привязкой своего банковского счета к ТСП. + +• Последующие платежи с привязанного счета в адрес данного ТСП будут выполняться без участия Плательщика. + +• Регистрация Функциональной ссылки СБП для выполнения оплаты с последующей привязкой счета представляет собой регистра +ссылки с "qrcType"="02" с дополнительным параметром "subscriptionPurpose" (информация от ТСП с деталями привязки счета). + +2.1 Метод GetQRCd + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1… +50) + +y Тип запроса. Константа «GetQRCd». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +width String o Ширина картинки QR-кода (только числовое значение). + +height String o Высота картинки QR-кода (только числовое значение). + +qrcType String (n-2) y Тип запрашиваемого QR-кода. Константа — «02». + +paymentPurpose String (ans- + +140) + +o Назначение платежа. + +messageID String (an-1… +1024) + +o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +qrTtl String (an-1… + +6) + +o Срок жизни Функциональной ссылки СБП в минутах. Минимальное допустимое значение — «1». + +значение — «129 600» (90 дней). + +Рекомендация: устанавливать срок жизни Функциональной ссылки СБП не менее «5» минут. Ес + +в запросе, будет использовано значение по умолчанию — «4 320» минут (3 суток). + +queryData.notificationUrl String (ans- + +512) + +y Полный URL для получения уведомления о финальном статусе оплаты QR-кода, а также о результа + +queryData.notificationUrl_sub String (ans- +512) + +o Полный URL для получения уведомления о результате привязки счета. + +В случае указания значения в данном поле, на указанный URL адрес будет направлено одно отд + +привязки счета Плательщика. + +{ + + "command":"subscription/notification", + + "сode":"RQ05030", + + "message":"Плательщик отказался от привязки счета", + + "status":"RJCT", + + "qrcId":"BB1S0053V5S91S2E83RPL8THQSRS7O8K", + + "subscriptionToken":"00000000000000000000000000000000", + + "memberId ":"100000000008" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 4/13 + + + +Код ключа Тип данных required Назначение + +subscriptionPurpose String (ans- + +140) + +y Цель привязки счета. Информация от ТСП с деталями привязки счета. Данная информация буде + +Плательщика при оформлении привязки счета в ДБО Банка Плательщика. + +Рекомендуется указывать подробную информацию о привязке счета, включая, если применимо + +регулярных платежей и прочее*. + +redirectUrl String (ans- + +1024) + +o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. Допускаются тольк + +должен соответствовать правилам кодировки URL. + +Если все же требуется использовать в redirectUrl кириллические символы, необходимо перекодиров +код, используя percent-encoded octets согласно RFC3986. + +Если требуется сформировать QR-код для привязки дополнительного счёта Плательщика в том же Б + +Код ключа Тип +данных required Назначение + +subscriptionServiceId String (32) o Идентификатор привязки. Обязательно при наличии subscriptionServiceName, т. к. параметры subscriptionSe + +могут быть переданы только вместе. При получении параметров subscriptionServiceId и subscriptionServiceN + +использовать их в ходе проверки данных привязки счёта на уникальность. + +subscriptionServiceName String (70) o Наименование привязки. Обязательно при наличии subscriptionServiceId, т. к. параметры subscriptionService +быть переданы только вместе. При получении параметров subscriptionServiceId и subscriptionServiceName Б + +использовать их в ходе проверки данных привязки счёта на уникальность. + +Если требуется сформировать динамический QR-код под определенного Плательщика, то необходимо использоват + +Код ключа Тип данных required Назначение + +queryData.SenderFIO String (an-140) o Фамилия, Имя и Отчество Плательщика (не является регистрозависимым) + +queryData.SenderID String (an-11.13) o Идентификатор Плательщика (номер телефона Плательщика — 0079123456 + +queryData.SenderBankBIC String (n-9) o БИК Банка Плательщика + +Важно! При отсутствии данных в параметре subscriptionPurpose будет зарегистрирована обычная одноразовая Платежная ссылка СБ +возможности совершить привязку счета. + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +1 { + +2 "command":"GetQRCd", + +3 "TermNo":"90080567", + +4 "amount":"10000", + +5 "currency":"RUB", + +6 "qrcType":"02", + +7 "paymentPurpose":"Назначение платежа", + +8 "subscriptionPurpose":"Подписка на оплату услуг Интернет 500р./мес.", + +9 "width":"600", + +10 "height":"600", + +11 "qrTtl":"10", + +12 "messageID":"message", + +13 "queryData": + +14 { + +15 "notificationUrl":"https://sbp-payments", + +16 "notificationUrl_sub":"https://sbp-subscription" + +17 }, + +18 "redirectUrl": "https://exampletsp.io/qwertyui" + +19 } + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 5/13 + + + +Код +ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +image String(an) + +Длинна зависит от формата, порядок + +7000 символов. + +y Изображение QR-кода содержит энкодированный BASE64 файл изображени +.png + +message String (ans-1024) y Расшифровка кода ответа**. + +payload String (1…999) y Платежная ссылка***. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка + +qrcId String (an-32) y Идентификатор QR-кода + +status String (n-7) y Статус регистрации Платежной ссылки СБП + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +• https://qr.nspk.ru/BD1P004FM8U22B8B8N1RHCRJSAB6C4TS + +• https://qr.nspk.ru/BD1P004FM8U22B8B8N1RHCRJSAB6C4TS?type=02&bank=100000000008&sum=100&cur=RUB&crc=A1A3 + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +Результатом выполнения запроса «Оплата по QR-коду с последующей привязкой/подпиской по СБП» является передача Банком Пла +следующих параметров: + +1. «subscriptionToken» — Уникальный Идентификатор привязки счета, назначаемый Банком Плательщика; + +2. «memberId» – Идентификатор банка Плательщика. + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "image":"iVBORw0KGgoAAAANSUhEUgAAghjysAAAAgjjafggkqqBEoAAARKCAIAAAQA/w……………...........YIAI", + +5 "message":"%u0423%u0441%u043F%u0435%u0445", + +6 "messageID":"message", + +7 "payload":" https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJLK", + +8 "payrrn":"000022134348", + +9 "qrcId":"AS1000670LSS7DN18SJQDNP4B05KLJLK ", + +10 "status":"CREATED" + +11 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 6/13 + +https://qr.nspk.ru/BD1P004FM8U22B8B8N1RHCRJSAB6C4TS%20 +https://qr.nspk.ru/BD1P004FM8U22B8B8N1RHCRJSAB6C4TS?type=02&bank=100000000008&sum=100&cur=RUB&crc=A1A3 + + +Важно: + +• Значения параметров "subscriptionToken" и "memberId" необходимо хранить в системе ТСП для дальнейшего использования ТСП в  +с привязанного счета по инициативе ТСП». В случае отсутствия или утери значения параметра "subscriptionToken", привязку счет +повторно. + +• Для получения значений параметров "subscriptionToken" и "memberId" ТСП необходимо реализовать возможность получения callba + +2.2. Нотификация по сценарию «Оплата по QR-коду с последующей привязкой счета/подпиской по СБП» + +Запросы о нотификации отправляются из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.no +«queryData.notificationUrl_sub» при направлении запроса «GetQRCd». + +Информация о возможных сценариях нотификации: + +1. При успешной оплате и успешной привязке счёта в адрес ТСП направляется два callback уведомления: +• об успешности оплаты по QR-коду — метод «qrc/notification»; + +• об успешности привязки счета — метод «subscription/notification». + +2. Если Плательщик совершил оплату, но отказался от привязки счета, то в ТСП направляется два callback уведомления: +• об успешности оплаты по QR-коду (метод «qrc/notification»); + +• об отказе Плательщика от привязки счета (метод «subscription/notification»). + +3. Если Плательщик не стал совершать оплату, то привязка счета ему не предлагается, в ТСП callback уведомление не направляется. + +3. Оплата с привязанного счёта по инициативе ТСП + +Запрос «Оплата с привязанного счета по инициативе ТСП» позволяет по запросу ТСП выполнить оплату в рамках операции СБП C2B +привязка которого была выполнена ранее в рамках запроса «Регистрация QR-кода для привязки счета/подписки по СБП» или «О +с последующей привязкой счета/подпиской по СБП». Сценарий может применяться как для разовых, так и для регулярных плате + +Для выполнения оплаты с привязанного счета необходимо направить в платежный шлюз Банка два последовательных запроса: + +1. Запрос «GetQRCd» на генерирование Платежной ссылки со значением параметра qrcType = «02» и с обязательно заполненным зн +«paymentPurpose»; + +2. Запрос «QRCSubPayPetition» на оплату с привязанного счёта с указанием: +• идентификатора QR-кода, полученного в ответе на запрос GetQRCd; + +• идентификаторов «subscriptionToken» и «SenderMemberId», полученных в callback уведомлении по методу «subscription/notificatio + +В случае удаления Плательщиком привязки счета Банк Плательщика, получив запрос по сценарию «Оплата с привязанного счета по +запрос и направляет в адрес ТСП нотификацию с сообщением — «Привязка счета не найдена». + +Оплату с привязанного счета можно проводить на сумму до 1 000 000 руб. + +3.1. Генерация Платежной ссылки + +Метод «GetQRCd» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1… + +50) + +y Тип запроса. Константа «GetQRCd». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +amount Number y Сумма платежа в минорных единицах (копейках). + +currency String (ans-3) y Код валюты (для рублей должен передаваться «RUB»). + +width String o Ширина картинки QR-кода (только числовое значение). + +height String o Высота картинки QR-кода (только числовое значение). + +qrcType String (n-2) y Тип запрашиваемого QR-кода. Константа — «02». + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 7/13 + + + +Код ключа Тип данных required Назначение + +paymentPurpose String (ans- + +140) + +y Назначение платежа. Обязательно к заполнению в сценарии «Оплата с привязанного счета по и + +messageID String (an-1… +1024) + +o Уникальный идентификатор сообщения, GUID. Только латинские символы! + +qrTtl String (an-1… + +6) + +o Срок жизни Функциональной ссылки СБП в минутах. Минимальное допустимое значение — « + +значение — «129 600» (90 дней). + +Рекомендация: устанавливать срок жизни Функциональной ссылки СБП не менее «5» минут + +в запросе, будет использовано значение по умолчанию — «4 320» минут (3 суток). + +queryData.notificationUrl String (ans- + +512) + +y Полный URL для получения уведомления о решении Банка Плательщика по оплате с привязанн + +статусе оплаты QR-кода. + +queryData.notificationUrl_subRes String (ans- + +512) + +o Полный URL для получения уведомления о решении Банка Плательщика по оплате с привяз + +В случае указания значения в данном поле, на указанный URL адрес будет направлено одно + +о решении Банка Плательщика по оплате с привязанного счета. + +redirectUrl String (ans- + +1024) + +o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. Допускаются то + +Формат должен соответствовать правилам кодировки URL. +Если все же требуется использовать в redirectUrl кириллические символы, необходимо перекоди + +код, используя percent-encoded octets согласно RFC3986. + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код +ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +TermNo String (an-20) y Уникальный идентификатор терминала. + +image String (an) + +Длинна зависит от формата, порядок + +7000 символов. + +y Изображение QR-кода содержит энкодированный BASE64 файл изображени +.png + +message String (ans-1024) y Расшифровка кода ответа**. + +messageID String (ans-1024) o Уникальный идентификатор сообщения, GUID. + +payload String (1…999) y Платежная ссылка***. + +1 { + +2 "command":"GetQRCd", + +3 "TermNo":"90080567", + +4 "amount":"10000", + +5 "currency":"RUB", + +6 "qrcType":"02", + +7 "paymentPurpose":"Назначение платежа", + +8 "width":"600", + +9 "height":"600", + +10 "qrTtl":"10", + +11 "messageID":"message", + +12 "queryData": + +13 { + +14 "notificationUrl":"https://sbp-payments", + +15 "notificationUrl_subRes":"https://sbp-subscription_ resolution" + +16 }, + +17 "redirectUrl": "https://exampletsp.io/qwertyui" + +18 } + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 8/13 + + + +Код +ключа Тип данных required Назначение + +payrrn String (n-12) y Референсный идентификатор запроса в системе Банка. + +qrcId String (an-32) y Идентификатор QR-кода. + +status String (n-7) y Статус регистрации Платежной ссылки СБП + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +*** Формат payload может быть двух видов: + +• https://qr.nspk.ru/AD10000BBJKO23GB98LA1FGBRIHH3K89 + +• https://qr.nspk.ru/AD10000BBJKO23GB98LA1FGBRIHH3K89?type=02&bank=100000000008&sum=10000&cur=RUB&crc=D87E + +d) Примерный формат ответа: + +• 200 OK + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +3.2. Запрос на оплату с привязанного счета по инициативе ТСП + +Метод QRCSubPayPetition используется ТСП для того, чтобы Банк Плательщика выполнил оплату с привязанного счета. + +Метод «QRCSubPayPetition» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «QRCSubPayPetition». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +subscriptionToken String (an-32) y Идентификатор Привязки счета, назначенный Банком Плательщика ранее на этапе оформления п + +SenderMemberId String (an-12) y Идентификатор банка Плательщика. + +qrcId String (an-32) y Идентификатор QR-кода. + +1 { + +2 "ErrorCode": 0, + +3 "TermNo": 90080567, + +4 "image": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAYAAAC + +5 "message": "%u0423%u0441%u043F%u0435%u0445", + +6 "messageID": "message", + +7 "payload": "https://qr.nspk.ru/AD10000BBJKO23GB98LA1FGBRIHH3K89?type=02&bank=100000000008&sum=10 + +8 "payrrn": "000755856505", + +9 "qrcId": "AD10000BBJKO23GB98LA1FGBRIHH3K89", + +10 "status": "CREATED" + +11 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + + } + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 9/13 + +https://qr.nspk.ru/AD10000BBJKO23GB98LA1FGBRIHH3K89 +https://qr.nspk.ru/AD10000BBJKO23GB98LA1FGBRIHH3K89?type=02&bank=100000000008&sum=10000&cur=RUB&crc=D87E + + +* Если привязка счета была подтверждена Плательщиком, Банк Плательщика в обязательном порядке должен передать параметр « +Уникальный Идентификатор привязки счета. Уникальный Идентификатор привязки счета должен однозначно идентифицировать со +Плательщика. + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +message String (ans-140) y Расшифровка кода ответа**. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +3.3. Нотификация по сценарию «Оплата с привязанного счёта по инициативе ТСП» + +Запросы о нотификации отправляются из ПШ Банка во внутреннюю систему ТСП на URL адрес, указанный в параметре «queryData.no +«queryData.notificationUrl_subRes» при направлении запроса «GetQRCd». + +Нотификация по оплате с привязанного счёта состоит из двух уведомлений: + +1. Уведомление о согласии/отказе в проведении платежа — метод «resolution /notification»; + +2. Уведомление о проведении/отказе в проведении платежа по QR-коду — метод «qrc/notification». + +Метод «resolution /notification» + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «resolution/notification» + +code String (an-7) y Возможные варианты кодов ответа: + +«RQ00030» — Согласие Банка Плательщика на выполнение платежа + +{ + + "command":"QRCSubPayPetition ", + + "TermNo":"90080567", + + "subscriptionToken":"70LSS7DN18SJQRS10006DNPKLJL24B05" + + "SenderMemberId":"100000000008", + + "qrcId":" AD10000BBJKO23GB98LA1FGBRIHH3K89" + +} + +{ + + "ErrorCode":"RQ00000", + + "message":"Запрос обработан успешно" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 10/13 + + + +Код ключа Тип данных required Назначение + +«RQ05031» — Отказ Банка Плательщика. Привязка счета не найдена + +«RQ05032» — Отказ Банка Плательщика в выполнении платежа + +«RQ05060» — Недостаточно денежных средств для проведения операции + +«RQ05061» — Превышен лимит по сумме операций по СБП + +«RQ05062» — Превышен лимит по количеству операций по СБП + +«RQ05063» — Подозрение в мошенничестве + +«RQ05064» — Выполнение операций в данной категории ТСП запрещено + +«RQ05065» — Счёт заблокирован + +«RQ05066» — Счёт закрыт + +«RQ05067» — Выполнение операции запрещено по требованию законодательства + +message String (ans-1…1024) y Расшифровка кода ответа*. + +qrcId String (an-32) y Идентификатор QR-кода + +* Таблица возможных кодов ответа приведена в приложении 2. + +b) Примерный формат запроса при успешной оплате с привязанного счета: + +c) Примерный формат запроса в случае если недостаточно денежных средств на счёте Плательщика/сумма больше установленного + +d) Примерный формат запроса в случае направления запроса ТСП на оплату с привязанного счета, когда привязка счета была успеш +Плательщиком удалена: + +e) ВС ТСП отвечает http-кодом «200» — успешное получение нотификации, или ошибкой. + +В настоящий момент ответ ВС не обрабатывается шлюзом Альфа-Банка. Обработка ответов ТСП находится в разработке. + +В случае добавления со стороны НСПК дополнительных параметров уведомления, система принимающая их от шлюза Альфа-Банка +такие неожиданные параметры как ошибочный запрос. + +4. Запрос статуса привязки счёта + +Запрос предназначен для попытки уточнения в ПШ Банка привязки счета со стороны ТСП. + +Метод GetQRCSubStatus. + +{ + + "command":"resolution/notification ", + + "code":" RQ00030", + + "message":" Согласие на проведение платежа ", + + "qrcId":" BD10006FEU7CQ9VE8D383VP0O2VH78D9", + +} + +{ + + "command":" resolution/notification ", + + "code":" RQ05032", + + "message":" Отказ в выполнении платежа ", + + "qrcId":" BD10004KH55FOMC48QIR3FCDEHVLA23F ", + +} + +{ + + "command":" resolution/notification ", + + "code":"RQ05031", + + "message":"Привязка счета не найдена ", + + "qrcId":" BD10004KH55FOMC48QIR3FCDEHVLA23F ", + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 11/13 + + + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «GetQRCSubStatus». + +TermNo String (an-20) y Уникальный идентификатор терминала. + +qrcId String(an-32) y Идентификатор QR-кода. + +RQperiod String(n-3) o Период времени, за который нужно искать уведомление для Агенета ТСП о решении Банка Плательщика по пр + +*Если параметр не передан в запросе, то поиск будет осуществляться без ограничения по времени. + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа*. + +message String (ans-140) y Расшифровка кода ответа**. + +qrcId String(an-32) o Идентификатор QR-кода. + +status String(a-4) o Статус выполнения привязки счета Плательщика. + +subscriptionToken String(an-32) o Уникальный идентификатор привязки счета Плательщика в Банке Плательщика. + +memberId String(an-12) o Идентификатор Банка Плательщика. + +notifyDate String(ans-19) o Дата получения уведомления о результате выполнения привязки счета Плательщика. + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +Примечание: + +• Если уведомление найдено, то в ответе будет присутствовать параметр «status». + +• Если в ходе выполнения запроса возникла ошибка обработки запроса, то в ответе будут переданы только код ошибки не равный + +• Если уведомление не было найдено (не получено от НСПК), то запрос будет считаться успешно выполненным и в ответе будет пер +соответствующее успешному ответу, но без дополнительных параметров. + +d) Примерный формат ответа: + +• 200 OK + +{ + + "command":"GetQRCSubStatus", + + "TermNo":"90080567", + + "qrcId":"BB1S002PRSK6SR3E9R7P0H077UKN1QVF", + + "RQperiod":"14" + +} + +{ + + "ErrorCode": 0, + + "memberId": 600000000015, + + "message": "OK", + + "qrcId": "BB1S002PRSK6SR3E9R7P0H077UKN1QVF", + + "status": "ACWP", + + "subscriptionToken": "70LSS7DN18SJQRS10006DNPKLJLAGT77" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 12/13 + + + +Примечание: текстовые данные передаются в формате urlencoded. + +• 400 Bad Request + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Привязка счёта / подписка СБП + +https://alfabank.ru/sme/payservice/sbp/docs/subscription/?rp-menuOpen=1 13/13 + + diff --git a/_docs/alfabank/qr_payout/7_digital_rubble.md b/_docs/alfabank/qr_payout/7_digital_rubble.md new file mode 100644 index 0000000..4f74fa2 --- /dev/null +++ b/_docs/alfabank/qr_payout/7_digital_rubble.md @@ -0,0 +1,1101 @@ +Цифровой Рубль + +Цифровой рубль + +Цифровой рубль — это цифровая форма рубля. + +Сейчас у нас есть наличная (банкноты и монеты) и безналичная (деньги на счетах) форма национальной валюты, а в дополнение к ни + +Счета цифрового рубля будут открываться на платформе Центробанка. На этих счетах будет храниться цифровой рубль. + +Операции с цифровыми рублями будут проходить на ПЦР. + +Доступ к счетам цифрового рубля будет возможен через мобильные приложения банков и интернет-банки. + +По эквайрингу прием ЦР осуществляется в рамках Универсального платёжного кода + +1. Динамический QR-код: + +1.1. Запрос регистрации динамического УПК (универсального одноразового платёжного кода) + +• Сгенерировать универсальный одноразовый платёжный код возможно с помощью уже существующего метода «GetQRCd». +Сгенерированный QR-код возможно оплатить как через СБП, так и с использованием ЦР. +При этом в настройках ТСП на ПШ Банка обязательно должен быть указан счет ЦР + +• Также универсальный одноразовый платёжный код возможно сгенерировать с помощью отдельного метода «ReqUniQr». +Сгенерированный QR-код возможно оплатить как через СБП, так и с использованием ЦР. +При этом в настройках ТСП на ПШ Банка обязательно должен быть указан счет ЦР + +Запрос «ReqUniQr» направляется ТСП в Банк для выполнения запроса «Регистрация универсальной платёжной ссылки» API СБП. + +В ответе ПШ Банка возвращает результат обработки запроса и, в случае успешной обработки — значения параметров, полученных в  + +• image (изображение) + +• mediaTypeR (расширение QR-кода) + +• payload (платёжная ссылка) + +• uniQrId (Идентификатор Платёжной ссылки) + +• status (Статус регистрации Платёжной ссылки. Единственное допустимое значение = «CREATED»). + +Метод ReqUniQr + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an‐1…50) y Тип запроса. Константа «ReqUniQr» + +TermNo String (an‐20) y Уникальный идентификатор терминала + +amount Number о Сумма платежа в минорных единицах (копейках) + +Обязательна при значении uniQrType = 02 + +mediaType String o Расширение QR‐кода + +width String o Ширина картинки QR‐кода (только числовое значение) + +height String o Высота картинки QR‐кода (только числовое значение) + +uniQrType String (n‐2) y Тип платёжной ссылки: + +• 01 — многоразовая + +• 02 — одноразовая + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 1/13 + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 +https://sbp.nspk.ru/uniqr?ysclid=mhajjmr4i0196202211 +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1#dynemic_qr + + +Код ключа Тип данных required Назначение + +paymentPurpose String (ans‐140) o Назначение платежа + +redirectUrl String (ans‐1024) o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. + +Допускаются только символы в кодировке ASCII. Формат должен соответствовать правилам кодир + +Если требуется использовать в redirectUrl кириллические символы, необходимо перекодировать их + +RFC3986 + +paymentPageUrl String (ans‐1024) o Ссылка для перенаправления Покупателя на Платёжную страницу Участника Сервиса УПК + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID + +qrTtl String (an‐1…6) o Минимальное значение срока использования созданной динамической платёжной ссылки в целых мин + +fraudScore String (an‐16) o Индикатор Подозрительной Операции Агента ТСП + +queryData.notificationUrl String (ans‐512) o Полный URL для получения уведомления о финальном статусе оплаты QR‐кода + +Если требуется сформировать динамический QR-код под определенного Плательщика, то необходи + +Код ключа Тип данных required Назначение + +queryData.SenderFIO String (an‐140) o Фамилия, Имя и Отчество Плательщика, не являет + +queryData.SenderID String (an-11…13) o Идентификатор Плательщика + +queryData.SenderBankBIC String (n‐9) o Банковский Идентификационный Код Банка Плате + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an‐20) y Код ответа: + +0 — успешное выполнение запроса + +иначе — код ошибки и её расшифровка в поле message* + +message String (ans‐1024) o Расшифровка кода ответа — если ErrorCode не равен 0** + +payload String (1…999) o Платёжная ссылка — если ErrorCode = 0 + +1 { + +2 "command":"ReqUniQr", + +3 "TermNo":"90080567", + +4 "amount":"10000", + +5 "uniQrType":"02", + +6 "redirectUrl":"https://alfabank.ru/sme/payservice/sbp/", + +7 "paymentPageUrl":"https://alfabank.ru/sme/payservice/sbp/", + +8 "mediaType":"image/png", + +9 "width":"600", + +10 "height":"600", + +11 "qrTtl":"2", + +12 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +13 "paymentPurpose":"Назаначение платежа", + +14 "fraudScore":"0000000000000000", + +15 "queryData": + +16 { + +17 "notificationUrl":"https://sbp-payments", + +18 "SenderFIO":"Иванов|Иван|Иванович", + +19 "SenderID":"0079123456789", + +20 "SenderBankBIC":"44525593" + +21 } + +22 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 2/13 + + + +Код ключа Тип данных required Назначение + +payrrn String (n‐12) o Референсный номер платежа — если ErrorCode = 0 + +mediaTypeR String o Расширение QR-кода — если ErrorCode = 0 + +uniQrId String (an‐32) o Идентификатор Платёжной ссылки — если ErrorCode = 0 + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID — если ErrorCode = + +status String (an‐20) o Статус регистрации Платёжной ссылки = «CREATED» — если Error + +*,** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +1.2. Запрос статуса оплаты по динамическому УПК + +• Статус оплаты универсального одноразового платёжного кода возможно проверить с помощью уже существующего метода «GetQ +При этом, в ответе к уже существующим статусам, добавляется еще два новых статуса для ЦР: «ENDD» и «ACDR» + +• Также статус оплаты возможно проверить с помощью отдельного метода «GetUniQrStatus» + +Метод GetUniQrStatus + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an‐1…50) y Тип запроса. Константа «GetUniQrStatus» + +TermNo String (an‐20) y Уникальный идентификатор терминала + +uniQrIds String y Массив идентификаторов Одноразовых Платёжных ссылок (uniQrId), статус которых х + +Максимальное количество идентификаторов Одноразовых Платёжных ссылок в одно + +b) Примерный формат запроса: + +1 { + +2 "ErrorCode":"0", + +3 "message":"Запрос выполнен", + +4 "image":"iVBORw0KGgoAAAANS…AAASUVORK5CYII=", + +5 "messageID":"message", + +6 "payload":"https://qr.nspk.ru/BD10006PV41C82I48OAODKVDFF0IK9SE", + +7 "payrrn":"000000002235", + +8 "uniQrId":"BD10006PV41C82I48OAODKVDFF0IK9SE", + +9 "mediaTypeR":"image/png", + +10 "status":"CREATED" + +11 } + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +1 { + +2 "command": "GetUniQrStatus", + +3 "TermNo": "agttest321", + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 3/13 + +https://alfabank.ru/sme/payservice/sbp/docs/dynamic/?rp-menuOpen=1#payment_status + + +с) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an‐20) y Код ответа: + +0 — успешное выполнение запроса + +иначе — код ошибки и её расшифровка в поле message* + +message String (ans‐1024) o Расшифровка кода ответа — если ErrorCode не равен 0** + +data String o Блок данных в формате JSON (массив Record)*** — если ErrorCode + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID — если ErrorCode = 0 + +status String (an‐20) o Статус регистрации Платёжной ссылки = «CREATED» — если ErrorC + +*, ** Таблица возможных кодов ответа приведена в приложении 2. +*** описание структуры массива Record блока данных data: + +Код ключа Тип данных Назначение + +uniQrId String (an‐32) Идентификатор Одноразовой Платёжной ссылки + +code String (7) Код ответа для указанной Одноразовой Платёжной ссылки + +message String (1…255) Текстовое описание кода ответа для указанной Одноразовой Платёжной ссылки + +paymentServiceId String (12) Идентификатор способа приёма платежа, который использовался для оплаты указанной Одноразовой Платёжной сс + +Будет отсутствовать в ответе при значении параметра status = «NTST» и будет заполнен при любых других значениях + +status String (4) Текущий статус Одноразовой Платёжной ссылки. Допустимые значения: + +1. «NTST» (NOT_STARTED): платёж не инициирован + +2. «RCVD» (RECEIVED): инициирован платёж + +3. «ACWP» (ACCEPTED): платёж успешно выполнен + +4. «RJCT» (REJECTED): платёж отклонён + +5. «ENDD»: платёж с расчётами в ЦР обработан, но результат выполнения неизвестен (успех или отказ) + +6. «ACDR»: передаётся статус (аналог «ACWP»), указанный в настройке ACWPstatusDR. Используется в отдельных п + +Может принимать значения: + +• «ENDD» передаётся в случае, если: + +• с использованием указанной Одноразовой Платёжной ссылки была выполнена Операция ЦР C2B (paymentSe + +• нет уведомления, но уже был запрос статуса, и в нём был получен «ENDD» (если ссылка была сформирована + +• «ACWP» и «RJCT» только в том случае, если с использованием указанной Одноразовой Платёжной ссылки был + +• «ACDR» передаётся статус, если есть уведомление от ПлЦР об оплате (если ссылка была сформирована как un + +trxId String (32) Идентификатор Операции СБП будет заполнен только при соблюдении следующих условий: + +• paymentServiceId = «PS0000000001» + +4 "uniQrIds": + +5 [ + +6 "AD2000670LSS7DN18SJQDNP4B05KLJL1", + +7 "AD2000670LSS7DN18SJQDNP4B05KLJL2", + +8 "AD2000670LSS7DN18SJQDNP4B05KLJL3", + +9 "AD2000670LSS7DN18SJQDNP4B05KLJL4", + +10 "AD2000670LSS7DN18SJQDNP4B05KLJL5" + +11 ] + +12 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 4/13 + +https://wiki.finstream.ru/pages/viewpage.action?pageId=153813196#id-%D0%A8%D0%BB%D1%8E%D0%B7FastPayAgentDR(%D0%9F%D0%BB%D0%B0%D1%82%D0%B5%D0%B6%D0%BD%D0%B0%D1%8F%D1%81%D1%81%D1%8B%D0%BB%D0%BA%D0%B0%D0%A1%D0%91%D0%9F/%D0%A6%D0%A0(%D0%A6%D0%B8%D1%84%D1%80%D0%BE%D0%B2%D0%BE%D0%B9%D1%80%D1%83%D0%B1%D0%BB%D1%8C)%D0%B4%D0%BB%D1%8F%D0%90%D0%B3%D0%B5%D0%BD%D1%82%D0%B0%D0%A2%D0%A1%D0%9F)-%D0%91%D0%B8%D0%B7%D0%BD%D0%B5%D1%81-%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81AWGW.FastPayAgentDR.BProcess + + +Код ключа Тип данных Назначение + +• status = «ACWP» или «RJCT» + +kzo String (1…128) Контрольное значение Операции СБП будет заполнено только при соблюдении следующих условий: + +• paymentServiceId = «PS0000000001» + +• status = «ACWP» + +payrrn String (n‐12) Референсный номер платежа — если ErrorCode = 0 + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +2. Кассовая платёжная ссылка + +1 { + +2 "ErrorCode": "0", + +3 "message": "Запрос обработан успешно", + +4 "data": [ + +5 { + +6 "qrcId": "AD2000670LSS7DN18SJQDNP4B05KLJL1", + +7 "code": "RQ00000", + +8 "message": "Запрос обработан успешно", + +9 "paymentServiceId": "PS0000000002", + +10 "status": "ENDD", + +11 "trxId": null, + +12 "kzo": null + +13 }, + +14 { + +15 "qrcId": "AD2000670LSS7DN18SJQDNP4B05KLJL2", + +16 "code": "RQ00000", + +17 "message": "Запрос обработан успешно", + +18 "paymentServiceId": "PS0000000001", + +19 "status": "ACWP", + +20 "trxId": "A1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K3", + +21 "kzo": "FDOS4JUETLYT639ADAFZ4GAUY9VSM2TG2Y595LQ20EKQF3JM1CIV4ZTZYA1EYIMFMEJSRB2UR7KATMA2 + +22 }, + +23 { + +24 "qrcId": "AD2000670LSS7DN18SJQDNP4B05KLJL4", + +25 "code": "RQ00000", + +26 "message": "Запрос обработан успешно", + +27 "paymentServiceId": null, + +28 "status": "NTST", + +29 "trxId": null, + +30 "kzo": null + +31 }, + +32 { + +33 "qrcId": "AD2000670LSS7DN18SJQDNP4B05KLJL5", + +34 "code": "RQ05014", + +35 "message": "Указанное значение uniQrId не найдено", + +36 "paymentServiceId": null, + +37 "status": null, + +38 "trxId": null, + +39 "kzo": null + +40 } + +41 ] + +42 } + +{ + + "ErrorCode": "Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 5/13 + + + +2.1 Запрос регистрации кассового УПК (универсального многоразового платёжного кода) + +• Сгенерировать универсальный многоразовый платёжный код возможно с помощью уже существующего метода «RegCashQRc». +Сгенерированный QR-код возможно оплатить как через СБП, так и с использованием ЦР. +При этом в настройках ТСП на ПШ Банка обязательно должен быть указан счет ЦР + +• Также универсальный многоразовый платёжный код возможно сгенерировать с помощью отдельного метода «RegCashUniQr». +Сгенерированный QR-код возможно оплатить как через СБП, так и с использованием ЦР. +При этом в настройках ТСП на ПШ Банка обязательно должен быть указан счет ЦР + +Метод ReqUniQr + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an‐1…50) y Тип запроса. Константа «ReqCashUniQr» + +TermNo String (an‐20) y Уникальный идентификатор терминала + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID + +redirectUrl String (ans‐1024) o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. + +Допускаются только символы в кодировке ASCII. Формат должен соответствовать правилам кодир + +Если требуется использовать в redirectUrl кириллические символы, необходимо перекодировать их + +RFC3986 + +paymentPageUrl String (ans‐1024) o Ссылка для перенаправления Покупателя на Платёжную страницу Участника Сервиса УПК + +mediaType String o Расширение QR‐кода УПК + +width String o Ширина картинки QR‐кода (только числовое значение) + +height String o Высота картинки QR‐кода (только числовое значение) + +qrcId String (32) o Идентификатор Многоразового УПК, предварительно зарегистрированный с использованием мето + +Если Банк ТСП передаст в запросе параметр qrcId, Оператор Сервиса УПК использует значение это + +параметр qrcId будет отсутствовать, Оператор Сервиса УПК сформирует новое значение идентифи + +Зарегистрировать Кассовый УПК с определенным значением qrcId может только тот Банк ТСП, кот + +API «Получение идентификаторов для Многоразовых УПК» + +queryData.notificationUrl String (ans‐512) o Полный URL для получения уведомления о финальном статусе оплаты QR-кода + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +1 { + +2 "command":"ReqCashUniQr", + +3 "TermNo":"90080567", + +4 "messageID":"f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +5 "redirectUrl":"https://alfabank.ru/sme/payservice/sbp/", + +6 "paymentPageUrl":"https://alfabank.ru/sme/payservice/sbp/", + +7 "mediaType":"image/png", + +8 "width":"600", + +9 "height":"600", + +10 "qrcId":"", + +11 "queryData": + +12 { + +13 "notificationUrl":"https://sbp-payments", + +14 } + +15 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 6/13 + +https://alfabank.ru/sme/payservice/sbp/docs/paylink/?rp-menuOpen=1#cash_register_payment_link + + +Код ключа Тип данных required Назначение + +ErrorCode String (an‐20) y Код ответа* + +message String (ans‐1024) y Расшифровка кода ответа** + +TermNo String (an‐20) y Уникальный идентификатор терминала + +payload String (1…999) o Платёжная ссылка УПК. См. приложение 1 + +image String (an) + +Длина зависит от формата, порядок 7000 символов + +y Изображение QR-кода содержит энкодированный BASE64 + +mediaType String o Расширение QR-кода УПК, если ErrorCode = 0 + +qrcId String (an‐32) o Идентификатор QR-кода + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID — если Err + +status String (an‐20) o Статус регистрации Платёжной или Информационной ссы + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +2.2 Запрос статуса оплаты по кассовому УПК + +• Статус оплаты кассового универсального многоразового платёжного кода возможно проверить с помощью уже существующего м +При этом, в ответе к уже существующим статусам, добавляется ещё два новых статуса для ЦР: «ENDD» и «ACDR». + +• Также статус оплаты возможно проверить с помощью отдельного метода «GetCashUniQrStatus». + +Метод GetCashUniQrStatus + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an‐1…50) y Тип запроса. Константа «GetCashUniQrS + +TermNo String (an‐20) y Уникальный идентификатор терминала + +messageID String (ans‐1024) o Уникальный идентификатор сообщения + +{ + + "ErrorCode": "0", + + "message": "OK", + + "TermNo": "90080567", + + "payload": "![CDATA[https://qr.nspk.ru/BS2R003FS8EFGAVM852PQS13N894HDLU?type=01&bank=620000000015&cr + + "image": "iVBORw0KGgoAAAANSUhEUgAAAlg......", + + "mediaType": "image/png", + + "qrcId": "BS2R003FS8EFGAVM852PQS13N894HDLU", + + "status": "CREATED" + +} + +{ + + "ErrorCode":"Код ответа", + + "message":"Расшифровка кода ответа" + +} + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 7/13 + + + +Код ключа Тип данных required Назначение + +payrrn String (n‐12) o Референсный номер платежа + +uniQrId String (an‐32) y Идентификатор Кассового УПК + +paramsId String (an‐32) y Идентификатор параметров Кассового У + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an‐20) y Код ответа* + +message String (ans‐1024) y Расшифровка кода ответа** + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID — если ErrorCode = 0 + +uniQrId String (an‐32) o Идентификатор Кассового УПК + +payrrn String (n‐12) o Референсный номер платежа + +trxId String (an‐32) o Уникальный идентификатор платежа в НСПК. Идентификатор Операции СБП будет заполнен то + +• paymentServiceId = «PS0000000001» + +• status = «ACWP» или «RJCT» + +trxDT String (n‐14) o Дата и время платежа в AnyWay (ГГГГММДДччммсс) + +paymentServiceId String (12) o Идентификатор Платёжного сервиса, с использованием которого был выполнен Перевод УПК + +• «PS0000000001» — платёж через СБП + +• «PS0000000002» — платёж с использованием ЦР + +Будет отсутствовать в ответе при значении параметра status = «NTST» и будет заполнен при лю + +BatchId String (n‐1…8) o Уникальный идентификатор смены (если смена терминала была открыта), метод получения см. ан + +CreditDatePos String (ans 1‐256) o Дата операции, установленная Банком Получателя в ходе обработки уведомления НСПК (определ + +merchantId String (an‐20) o Id магазина в НСПК + +TermNo String (an‐20) y Уникальный идентификатор терминала + +amount Number o Сумма платежа в минорных единицах (копейках) + +currency String (ans‐3) o Код валюты (для рублей должен передаваться «RUB») + +Url String (ans 1‐512) o Полный URL для получения уведомления ТСП (значение параметра, переданного при регистрации + +cashRegisterQrcStatus String y Текущий статус Кассовой ссылки СБП для указанного paramsId: + +• «WAITING_PAYMENT» — Кассовая ссылка СБП для указанного paramsId активирована и готов + +{ + + "command": "GetCashUniQrStatus", + + "TermNo": "90080567", + + "messageID": " f9aa54ff-a615-44b8-aa6c-acab655c89f8", + + "payrrn": "000000000256", + + "uniQrId": "AS1R0006QD93NUCF9MIPLLLDD7BF49CI", + + "paramsId": "BP10001NAJ5S985L9DM9GO6PK4H6KN3M" + +} + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 8/13 + + + +Код ключа Тип данных required Назначение + +• «IN_PROGRESS» — Операция по Кассовой ссылке СБП для указанного paramsId в процессе вы + +• «DEACTIVATED» — Кассовая ссылка СБП с указанным paramsId более не существует (все дейс + +paramsId String‐32 y Идентификатор активного набора параметров + +kzo String (1…128) o Контрольное значение Операции СБП будет заполнено только при соблюдении следующих ус + +• paymentServiceId = PS0000000001» + +• status = «ACWP» + +status String (4) o Статус Перевода УПК. Допустимые значения: + +1. «NTST» — Перевод УПК не начат + +2. «RCVD» — Перевод УПК в процессе обработки + +3. «ENDD» — Перевод УПК завершён (только для оплаты ЦР) + +4. «ACWP» — Перевод УПК выполнен успешно (только для оплаты через СБП) + +5. «RJCT» — Перевод УПК отклонён (только для оплаты через СБП) + +6. «ACDR» — Перевод в ЦР выполнен успешно (аналог «ACWP»), если указан в настройке ACW + +timestamp UTC time format o Дата и время выполнения Операции СБП. Параметр будет заполнен только при соблюдении следу + +• paymentServiceId = «PS0000000001» + +• status = «ACWP» или «RJCT» + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +• «status» = «NTST», «RCVD» или «ACTC» — означает необходимость повтора запроса до получения одного из финальных статусов + +• Получение «status» = «RJCT» означает отказ в оплате данного QR-кода + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +1 { + +2 "ErrorCode": "0", + +3 "message": "Запрос выполнен", + +4 "TermNo": "90080567", + +5 "messageID": " f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +6 "uniQrId": "AS1R0006QD93NUCF9MIPLLLDD7BF49CI", + +7 "paramsId": "BP10001NAJ5S985L9DM9GO6PK4H6KN3M", + +8 "trxStatus": "ACWP", + +9 "payrrn": "000000000256", + +10 "timestamp": "2025-06-24T11:53:09.000Z", + +11 "cashRegisterQrcStatus": "DEACTIVATED", + +12 "trxId": "B5175115309809010000120011530503", + +13 "trxDT": "20250624115309", + +14 "amount": "100", + +15 "currency": "RUB", + +16 "Url": " https://sbp-payments", + +17 "CreditDatePos": "20250624", + +18 "payerId": "*********5744", + +19 "kzo": "45dfe048b805b1f7612a51b961ee61e5df008314a1a3c82892a085cacff18500e8c7f09170c10415fd26710a4a + +20 "merchantId": "MA0000018412", + +21 "paymentServiceId": "PS0000000001" + +22 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 9/13 + + + +2.3. Изменение параметров кассового УПК (универсального многоразового платёжного кода) + +Запрос «ChangeAccForCashUniQr» направляется ТСП в Банк для выполнения запроса УПК API «Изменение параметров Многоразово +отдельных параметров Многоразового или Кассового УПК, заданных при регистрации УПК. + +Для Многоразового или Кассового УПК могут быть изменены: + +• Уникальный идентификатор терминала (параметр TermNo) + +• Получатель денежных средств в Переводе УПК или ТСП получателя (параметр merchantId). Новое значение merchantId может прин +принадлежало прежнее значение merchantId, так и другому ЮЛ, ИП или Самозанятому, зарегистрированному в НСПК + +• Ссылка для автоматического возврата Покупателя из приложения Банка в приложение или на сайт ТСП (параметр redirectUrl) + +• Набор Платёжных сервисов, с использованием которых может быть выполнен Перевод УПК по данному Многоразовому/Кассовом +в Переводе УПК, выполненном с использованием того или иного Платёжного сервиса, например, Счет ТСП в Банке ТСП, на которы +выполнения Операции СБП C2B (параметры Account и AccountDR) + +В ответе ПШ Банка возвращает результат обработки запроса и, в случае успешной обработки — значения параметров, полученных в  + +Метод ChangeAccForCashUniQr + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1…50) y Тип запроса. Константа «ChangeAccForCashUniQr» + +TermNo String (an‐20) y Уникальный идентификатор терминала + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID + +qrcId String (32) o Идентификатор Кассового УПК + +account String (an‐20) o Новый счёт ЮЛ для УПК: + +если заполнено — будет изменён счёт для оплаты через СБП в УПК +если не заполнено — значение берётся из поля Account справочника терминалов + +accountDR String (55) o Новый счёт ЮЛ для ЦР: + +если заполнено — будет изменён счёт для оплаты ЦР в УПК + +если не заполнено — значение берётся из поля AccountDR справочника терминалов + +NewTermNo String (an‐20) o Новый уникальный идентификатор терминала. +Поле обязательно, если НЕ переданы account, accountDR, NewMerchantId, redirectUrl + +NewMerchantId String (an‐12) o Новый Id мерчанта (магазина) в НСПК. + +Поле обязательно, если НЕ переданы account, accountDR, NewTermNo, redirectUrl + +redirectUrl String (ans‐1024) o Содержит ссылку для автоматического возврата в приложение или на сайт ТСП. + +Допускаются только символы в кодировке ASCII. Формат должен соответствовать правилам кодировки U + +Если требуется использовать в redirectUrl кириллические символы, необходимо перекодировать их в соот + +paymentPageUrl String (ans‐1024) o Ссылка для перенаправления Покупателя на Платёжную страницу Участника Сервиса УПК + +fraudScore String o Индикатор Подозрительной Операции Банка ТСП + +b) Примерный формат запроса: + +{ + + "ErrorCode": "Код ответа", + + "message": "Расшифровка кода ответа" + +} + +1 { + +2 "command": "ChangeAccForCashUniQr", + +3 "TermNo": "90080567", + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 10/13 + +https://wiki.finstream.ru/pages/viewpage.action?pageId=79692419#id-%D0%A8%D0%BB%D1%8E%D0%B7FastPayAgent%D0%B4%D0%BB%D1%8F%D0%B7%D0%B0%D1%8F%D0%B2%D0%BE%D0%BA%D0%A2%D0%A1%D0%9F-%D0%A2%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D0%B0%D0%BB%D1%8B +https://wiki.finstream.ru/pages/viewpage.action?pageId=79692419#id-%D0%A8%D0%BB%D1%8E%D0%B7FastPayAgent%D0%B4%D0%BB%D1%8F%D0%B7%D0%B0%D1%8F%D0%B2%D0%BE%D0%BA%D0%A2%D0%A1%D0%9F-%D0%A2%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D0%B0%D0%BB%D1%8B + + +Правила заполнения и интерпретации параметров: + +• В запросе должен быть заполнен хотя бы один из параметров: account, accountDR, NewTermNo, NewMerchantId, redirectUrl. Если ни  +ErrorCode = «90» и message = «Не указан ни один из обязательных параметров» + +• account — будет выполнено изменение счёта ЮЛ, ИП или самозанятого для расчётов через СБП зарегистрированного УПК. Если зн +из справочника терминалов + +• accountDR — будет выполнено изменение/добавление счета ЮЛ, ИП или самозанятого для расчётов ЦР зарегистрированного УПК. +берётся из справочника терминалов/ЮЛ + +• Если параметр accountDR был передан в запросе, но длина его значения отличается от 55 — будет возвращена ошибка c ErrorCode +Параметр accountDR должен содержать 55 символов» + +• NewTermNo — будет выполнено изменение номера терминала для зарегистрированной Кассовой ссылки СБП. Новый номер терми +или ТСТ указанного NewMerchantId запроса + +• NewMerchantId — будет выполнено изменение ТСТ для зарегистрированной Кассовой ссылки СБП. Если поле NewTermNo в запросе +перепривязка существующего TermNo к новому NewMerchantId + +• redirectUrl — будет выполнено изменение ссылки автоматического возврата в приложение или на сайт ТСП для зарегистрированно + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an‐20) y Код ответа* + +message String (ans‐1024) y Расшифровка кода ответа** + +messageID String (ans‐1024) o Уникальный идентификатор сообщения, GUID — если ErrorCode = 0 + +qrcId String (an‐32) o Идентификатор QR-кода + +TermNo String (an‐20) y Уникальный идентификатор терминала + +account String (an‐20) y/o Cчёт для оплаты через СБП. +В ответе должен присутствовать один из параметров account или accountDR, либо о + +accountDR String (55) y/o Cчёт для оплаты ЦР. + +В ответе должен присутствовать один из параметров account или accountDR, либо о + +merchantId String (an‐12) y Id мерчанта (магазина) в НСПК + +status String (an‐20) o Статус регистрации Платёжной или Информационной ссылки СБП («CREATED» — + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 ОК + +4 "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +5 "qrcId": "BS200031LP9DVTOR80O83FQ2ILIADFLM", + +6 "account": "40201810100000088000", + +7 "accountDR": "g.ab.cbrdc.wlt.clt.abcd0123-ab12-4a12-89ab-abcdef01234G", + +8 "redirectUrl": "https://alfabank.ru/sme/payservice/sbp/", + +9 "paymentPageUrl": " https://alfabank.ru/sme/payservice/sbp/", + +10 "fraudScore": "0000000000000000", + +11 "NewTermNo": "10000234", + +12 "NewMerchantId": "MA0000020651" + +13 } + +1 { + +2 "ErrorCode": "0", + +3 "message": "OK", + +4 "TermNo": "10000234", + +5 "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8", + +6 "qrcId": "BS200031LP9DVTOR80O83FQ2ILIADFLM", + +7 "account": "40201810100000088000", + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 11/13 + + + +• 400 Bad Request + +3. Нотификация Клиента-получателя об исполнении перевода ЦР С2B + +Сообщение отправляется из ПШ Банка на сервер ТСП и содержит Извещение Клиента-получателя об исполнении перевода ЦР (С2B) + +Метод paymentDR/notification + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an‐1…50) o Константа «paymentDR/notification» + +uniQrId String (an‐32) o Идентификатор платежа в системе ЮЛ‐получателя + +operationId String o Идентификатор операции на ПлЦР (значение из тега ЭС ) + +status String (an‐20) o Статус платежа на ПлЦР + +• если заполнено значение настройки ACWPstatusDR, то передаётся значение, указанное + +• «RCVD» — Перевод УПК в процессе обработки + +amount String (an‐1…12) o Сумма платежа в рублях с копейками + +timestamp YYYY-MM-DDThh:mm:ss[.SSS] o Дата и время исполнения распоряжения на ПлЦР + +payrrn String (n‐12) y Референсный номер платежа + +BatchId String (n‐4…8) y Уникальный идентификатор смены (если смена терминала открыта) + +TermNo String (an‐20) y Уникальный идентификатор терминала в AWGW + +CreditDatePos String (ans 1‐256) y Дата операции, установленная Банком Получателя в ходе обработки уведомления НСПК (опре + +merchantName ? y Наименование ТСП + +purpose String (ans‐210 y Назначение платежа + +b) Примерный формат запроса: + +8 "accountDR": "g.ab.cbrdc.wlt.clt.abcd0123-ab12-4a12-89ab-abcdef01234G", + +9 "status": "UPDATED", + +10 "merchantId": "MA0000020651" + +11 } + +{ + + "ErrorCode": "Код ответа", + + "message": "Расшифровка кода ответа" + +} + +1 { + +2 "command": "paymentDR/notification", + +3 "uniQrId": "AD2000670LSS7DN18SJQDNP4B05KLJL1", + +4 "operationId": "546464AX45546", + +5 "status": "ACWP", + +6 "amount": "10241.21", + +7 "timestamp": "2024-08-01T10:15:00.000Z", + +8 "payrrn": "102345678912", + +9 "BatchId": "998844", + +10 "TermNo": "90080567", + +11 "CreditDatePos": "20240802", + +12 "merchantName": "Рога и Копыта", + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 12/13 + + + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено) + +• http-код «500» — Внутренняя ошибка + +13 "purpose": "Кофе и булочка" + +14 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 13/13 + + diff --git a/_docs/alfabank/qr_payout/8_additional_methods_API.md b/_docs/alfabank/qr_payout/8_additional_methods_API.md new file mode 100644 index 0000000..2e1a915 --- /dev/null +++ b/_docs/alfabank/qr_payout/8_additional_methods_API.md @@ -0,0 +1,343 @@ +Дополнительные методы API + +Дополнительные методы API + +1. Запрос списка банков-участников СБП + +Запрос GetBankList направляется ТСП на ПШ Альфа-Банка для получения списка банков-участников СБП. + +Метод GetBankList + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1..50) y Тип запроса. Константа «GetBankList» + +messageID String (ans-1… + +1024) + +o Уникальный идентификатор сообщения, GUID + +BankMemberIdFilter String (n-11) o Фильтр для результатов запроса (указывается идентификатор участника СБП, добавляется в запрос если в + +ответе нужно получить данные только по одному банку) + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +BankList Массив o Коллекция, содержащая список банков-участников + +BankList.BankName String (an-50) o Наименование банка-участника + +BankList.BankID String (an-12) o Идентификатор участника СБП в НСПК + +BankList.BankBIK String (n-9) o БИК банка-участника СБП. (Присутствует в ответе если был передан из НСПК в данных участника СБП) + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +{ + + "command": "GetBankList" + +} + +1 { + +2 "ErrorCode": 0, + +3 "message":"Запрос обработан успешно", + +4 "BankList": + +5 [ { + +6 "BankName":"Наименование банка 1", + +7 "BankID":"10000001100", + +8 "BankBIK":"044525823" + +9 }, + +10 … + +11 { + +12 "BankName":" Наименование банка N", + +13 "BankID":"10000001145", + +12/23/25, 11:25 AM Дополнительные методы API + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 1/5 + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 + + +2. Запрос блокирования QR-кода + +Запрос направляется в ПШ банка в целях блокирования сгенерированного QR-кода. Запрос действует для любого вида сгенерирова +QR-кода. + +Метод BlockQRcId + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1..50) y Тип запроса. Константа «BlockQRcId» + +TermNo String (an-20) y Уникальный идентификатор терминала + +qrcId String (an-32) y Идентификатор QR-кода + +reason String (ans-1024) o Причина блокировки + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +TermNo String (an-20) y Уникальный идентификатор терминала + +message String (ans-1024) y Расшифровка кода ответа** + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +14 "BankBIK":"044525829" + +15 } + +16 ] + +17 } + +{ + + "command": "BlockQRcId", + + "TermNo": "90080567", + + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV", + + "reason": "Заказ 12345 направлен в стоп-лист" + +} + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "message": "OK" + +} + +{ + +"ErrorCode": "Код ответа", + +12/23/25, 11:25 AM Дополнительные методы API + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 2/5 + + + +3. Запрос разблокирования QR-кода + +Запрос направляется в ПШ банка в целях разблокирования ранее заблокированного QR-кода. + +Метод UnblockQRcId + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1..50) y Тип запроса. Константа «UnblockQRcId» + +TermNo String (an-20) y Уникальный идентификатор терминала + +qrcId String (an-32) y Идентификатор QR-кода + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +TermNo String (an-20) y Уникальный идентификатор терминала + +message String (ans-1024) y Расшифровка кода ответа** + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +4. Запрос списка заблокированных QR-кодов + +Запрос направляется в ПШ банка для получения списка заблокированных QR-кодов по определенному терминалу или кассе. + +"message": "Расшифровка кода ответа" + +} + +{ + + "command": "UnblockQRcId", + + "TermNo": "90080567", + + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV" + +} + +{ + + "ErrorCode": 0, + + "TermNo": 90080567, + + "message": "OK" + +} + +{ + +"ErrorCode":"Код ответа", + +"message": "Расшифровка кода ответа" + +} + +12/23/25, 11:25 AM Дополнительные методы API + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 3/5 + + + +Метод GetBlockedQRcIdList + +a) Описание параметров запроса: + +Код ключа Тип данных required Назначение + +command String (an-1..50) y Тип запроса. Константа «GetBlockedQRcIdList» + +TermNo String (an-20) y Уникальный идентификатор терминала + +b) Примерный формат запроса: + +c) Описание параметров ответа: + +Код ключа Тип данных required Назначение + +ErrorCode String (an-20) y Код ответа* + +message String (ans-1024) y Расшифровка кода ответа** + +QRcIdList Коллекция Список QRcId + +QRcIdList.qrcId String (an-32) y Идентификатор QR-кода + +QRcIdList.reason String (ans-1024) o Причина блокировки + +QRcIdList.date String (an-20) y Дата и время + +*, ** Таблица возможных кодов ответа приведена в приложении 2. + +d) Примерный формат ответа: + +• 200 OK + +• 400 Bad Request + +{ + + "command": "GetBlockedQRcIdList", + + "TermNo": "90080567", + +} + +1 { + +2 "ErrorCode": 0, + +3 "QRcIdList": + +4 [ + +5 { + +6 "date": "2024-04-18 17:17:45", + +7 "qrcId": "BD100000K5II0G369JHR3KBA6SM3FD3V", + +8 "reason": "Заказ 12345 направлен в стоп-лист" + +9 }, + +10 { + +11 "date": "2024-05-01 19:07:15", + +12 "qrcId": "BD100002JN871TSC9SJB7HPVRFD3HQ8T", + +13 "reason": "Заказ 96780 направлен в стоп-лист" + +14 } + +15 ], + +16 "TermNo": "90080567", + +17 "message": "OK" + +18 } + +{ + +"ErrorCode":"Код ответа", + +12/23/25, 11:25 AM Дополнительные методы API + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 4/5 + + + +"message": "Расшифровка кода ответа" + +} + +12/23/25, 11:25 AM Дополнительные методы API + +https://alfabank.ru/sme/payservice/sbp/docs/additional-api/?rp-menuOpen=1 5/5 + + diff --git a/_docs/alfabank/qr_payout/9_appendix.md b/_docs/alfabank/qr_payout/9_appendix.md new file mode 100644 index 0000000..5d476c8 --- /dev/null +++ b/_docs/alfabank/qr_payout/9_appendix.md @@ -0,0 +1,582 @@ +Приложения + +Приложения + +Приложение 1. Формат payload +В СБП используется формат двухмерного кода QR Code (ISO/IEC 18 004--2015). + +Payload QR-кода может быть представлен в двух вариантах: + +1. Короткий вариант Payload: https://HOST/QR_ID + +2. Длинный вариант Payload: https://HOST/QR_ID?type=QR_TYPE&bank=MEMBER_ID&sum=SUM&cur=CUR&crc=CRC + +Описание параметров URL-based payload: + +Параметр Описание required Формат + +HOST qr.nspk.ru — для QR_TYPE = 01 и 02 + +sub.nspk.ru — для QR_TYPE = 03 + +y String + +QR_ID Идентификатор зарегистрированного QR кода в СБП y String 32 символа + +QR_TYPE Тип QR кода: + +01 — QR Static (QR наклейка); + +02 — QR Dynamic (QR на кассе); + +03 — QR-Subscription (Оформление привязки счета). + +y String 2 цифры + +MEMBER_ID Идентификатор Банка Получателя (ТСП) (Member_ID) y String 12 символов + +SUM Сумма в копейках y (если QR_TYPE = 02); + +Отсутствует, если QR_TYPE = 03 + +String до 12 цифр + +CUR Валюта операции y (если присутствует SUM) String 3 символа + +CRC Значение контрольной суммы y String 4 символа + +Приложение 2. Описание кодов ответа +Полный перечень кодов представлен на сайте НСПК. Данная спецификация не описывает всего перечня кодов ответов т. к. в случае +исключительных ситуаций системой возможна генерация собственных кодов. Не описанные в документе коды следует обрабатыват +техническую (системную) ошибку. + +ErrorCode message + +«-999» Прочее сообщение FSCryptoProxy + +«-71» Неверные данные Basic авторизации запроса. Не прошла проверка авторизации запроса от fsCryptoProxy → GW + +«-9» Система перегружена. Повторите запрос через несколько секунд. Очередь: %1 + +«-8» Запрос отклонен. '%1' превышено ограничение на размер очереди. Ограничение: %2 Очередь: %3 + +«-7» Неверная подпись сообщения. Не прошла проверка связки запроса от fsCryptoProxy → GW, закрытый ключ, указанный в настройках fsCryptoProxy + +(proxyAlias) не соответствует открытому ключу, указанному в GW, продукции у БС в настройке PublicKeyFile + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 1/8 + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 +https://host/QR_ID +https://host/QR_ID?type=QR_TYPE&bank=MEMBER_ID&sum=SUM&cur=CUR&crc=CRC + + +ErrorCode message + +«-6» Не передана подпись сообщения в параметре Authorization заголовка + +«-5» Тип запроса %1 не поддерживается + +«-4» При получении данных возникли проблемы: %1 + +«-3» При создании потока JSON не образовался потоковый объект + +«-2» Возникли проблемы при преобразовании объекта в JSON %1 + +«-1» Возникли проблемы при обработке запроса %1 + +«0» «OK» + +«1» Внутренняя ошибка %1 + +«2» Терминал %1 не обнаружен + +«3» Не заполнены данные запроса %1 + +«301» Некорректно заполнены данные запроса %1 + +«4» Не передан qrcId или payrrn + +«5» Не получены данные от СПБ + +«8» Таймаут ответа, попробуйте позже + +«9» Ошибка идентификации, попробуйте позже + +«10» Не передан реквизит command + +«11» Данная команда не поддерживается + +«12» «Не найдены данные для возврата» + +«13» Не найден успешный ответ на вызов GetQRCreversalData по причине: %1 + +«14» Повторное открытие смены невозможно. Смена уже открыта. + +«15» Закрытие смены невозможно. Смена не открыта + +«16» Не передан TermNo + +«17» Не удалось найти QR по payrrn + +«18» Платеж не найден в запросах B07%1 + +«19» Платеж не найден в запросах B08%1 + +«20» Получен отказ на запрос возврата. Статус %1%2%3 + +«21» Не удалось получить получателя перевода + +«22» payrrn=%1 в запросе не соответствует данным qrcId=%2 у которого payrrn=%3 + +«23» Возврат невозможен для указанных параметров. Для payrrn=%1 соответствует trxId=%2, а в запросе получен %3 + +«24» Возврат невозможен для указанных параметров. Для qrcId=%1 соответствует trxId=%2, а в запросе получен %3 + +«25» «Терминал %1 заблокирован + +«26» «Ошибка идентификации» + +«27» «Невозможно выполнить возврат по данному Терминалу, т. к. счет зачисления не равен счету списания» + +«28» Запрос QR-кода не удался, не был получен Идентификатор QR-кода + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 2/8 + + + +ErrorCode message + +«29» Возврат невозможен. Для qrcId=%1 не удалось найти успешный ответ на запрос GetQRCstatus + +«30» Отсутствуют данные в переданных параметрах + +«31» Не удалось определить параметры: legalid или Для legalid не удалось найти данные в спр. счетов или в спр. клиентов + +«32» Отсутствуют данные получателя + +«33» Отсутствуют данные отправителя + +«34» Значения параметров запроса не совпадают с данными предыдущего шага + +«35» Не заполнен обязательный параметр REF + +«40» Возврат невозможен. Для payrrn=%1 не удалось найти успешный ответ на запрос GetQRCstatus + +«41» При активации кассовой ссылки, не удалось получить paramsId + +«42» Счет %1 не зарегистрирован у клиента. Изменение невозможно. + +«43» Данные об оплате еще не известны. По qrcId не получено уведомление (Notification) от НСПК + +«44» Кассовая ссылка зарегистрирована на устройстве #'%1' и может быть использована только на этом устройстве. + +«45» Общая Ошибка поиска архивной операции C2B + +«46» Ошибка поиска архивной операции C2B, по причине: %1 + +«47» Для выяснения статуса возврата необходимо передать один из параметров запроса: messageID, trxId или opkcRefundRequestId + +«48» Возврат с messageID '%1' на устройстве #'%2' не обнаружен + +«49» По возврату с messageID '%1' не обнаружен Идентификатор Операции СБП B2C по сценарию Возврат по Операции СБП C2B + +«50» Идентификаторы Операции СБП B2C по сценарию Возврат по Операции СБП C2B переданный в запросе '%1' отличается от данных возврата '%2' +полученного по messageID '%3' + +«51» Возврат по Идентификаторы Операции СБП B2C '%1' не обнаружен + +«52» Если передан реквизит opkcRefundRequestId запроса, то для выяснения статуса возврата необходимо также передать один из параметров запроса pa + +или originalTrxId + +«53» По данным payrrn '%1' не удалось определить Идентификатор исходной Операции СБП C2B + +«54» Не передан параметр LegalId + +«55» Не передан параметр quantity + +«67» ТСП '%1' не обнаружено с справочнике системы + +«68» Выплата по ТСП '%1' для устройства '%2' — запрещена + +«101» Тип запроса command='%1' не поддерживается + +«121» Возврат не может быть осуществлен, т. к. операция оплаты не имеет финального статуса + +«201» Получен отказ на запрос возврата. «Статус %1, Недостаточно средств на счете» + +«1001» «Сервис временно недоступен» + +«RQ00000» Запрос обработан успешно. + +«RQ00030» Согласие на выполнение платежа. + +«RQ00031» Ожидание решения по возврату от Банка Плательщика. + +«RQ02034» Некорректное значение code. + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 3/8 + + + +ErrorCode message + +«RQ03001» Ошибка валидации. Неверный формат запроса. + +«RQ05001» Значение agentId отсутствует в ОПКЦ СБП (Агент с указанным идентификатором не найден). + +«RQ05002» Значение memberId отсутствует в ОПКЦ СБП (участник с указанным идентификатором не найден). + +«RQ05003» Значение LegalId отсутствует в ОПКЦ СБП (юридическое лицо с указанным идентификатором не найдено). + +«RQ05004» Счет юридического лица не найден. + +«RQ05005» Значение merchantId отсутствует в ОПКЦ СБП (ТСП с указанным идентификатором не зарегистрировано в СБП). + +«RQ05006» Некорректное значение currency (код валюты). + +«RQ05007» Неверная версия шаблона Платежной или Информационной ссылки СБП (неверная версия шаблона QRC). + +«RQ05008» Неверный тип Платежной или Информационной ссылки СБП (неверный тип QRC). + +«RQ05009» Значение amount меньше минимально допустимого + +«RQ05010» Значение amount больше максимально допустимого + +«RQ05011» amount и currency должны одновременно присутствовать или одновременно отсутствовать при qrcType = 01 (QR-Static) + +«RQ05012» Отсутствует currency при qrcType = 02 (QR-Dynamic) + +«RQ05013» Отсутствует amount при qrcType = 02 (QR-Dynamic) + +«RQ05014» Значение qrcId не найдено + +«RQ05015» Превышено допустимое значение элементов в запросе + +«RQ05016» Некорректный формат qrcId + +«RQ05017» Некорректный формат или отсутствует paymentPurpose + +«RQ05018» Некорректный формат subscriptionPurpose + +«RQ05019» Отсутствует amount при активации Кассовой ссылки СБП + +«RQ05020» Период использования динамической Платежной ссылки СБП в поле qrTtl выходит за допустимый диапазон + +«RQ05021» Некорректный формат subscriptionToken + +«RQ05022» Невозможно деактивировать Кассовую ссылку СБП + +«RQ05023» qrTtl для Кассовой ссылки СБП выходит за допустимый диапазон + +«RQ05024» Некорректный формат redirectUrl + +«RQ05025» Отказ в смене счета ЮЛ, ИП или самозанятого. Кассовая ссылка СБП не деактивирована + +«RQ05026» Кассовая ссылка с указанным идентификатором уже существует + +«RQ05030» Отказ Банка Плательщика. Плательщик отказался от привязки счета + +«RQ05031» Отказ Банка Плательщика. Привязка счета не найдена + +«RQ05032» Отказ Банка Плательщика в выполнении платежа + +«RQ05033» Отказ в повторном платеже + +«RQ05034» Сценарий не поддерживается Банком Плательщика + +«RQ05035» Истекло время ожидания решения Банка Плательщика + +«RQ05036» Дублирование идентификатора запроса, назначаемого ТСП или Агентом ТСП, — agentRefundRequestId + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 4/8 + + + +ErrorCode message + +«RQ05037» Предыдущий запрос на возврат по Операции СБП C2B еще не обработан + +«RQ05038» Параметры запроса отличаются от параметров исходной Операции СБП C2B + +«RQ05039» Не найдена исходная Операция СБП C2B + +«RQ05040» Отказ от Банка Плательщика. Сумма возврата превышает сумму исходной Операции СБП C2B + +«RQ05041» Запрос на возврат по операции C2B не найден + +«RQ05042» Некорректный формат или отсутствует amount + +«RQ05043» Некорректный формат или отсутствует takeTax + +«RQ05044» Некорректный формат или отсутствует totalTaxAmount + +«RQ05045» Некорректный формат uip + +«RQ05046» Неверный тип платежной ссылки + +«RQ05047» Запрос на возврат с указанным идентификатором не найден + +«RQ05050» Сценарии с привязкой счета для ЮЛ/ИП недоступны + +«RQ05051» Решение выполнения оплаты с привязанного счета от Банка Плательщика еще не получено + +«RQ05052» Распоряжение от Банка Плательщика не было получено в ожидаемое время + +«RQ05053» От Банка Плательщика было получено положительное решение об оплате с привязанного счета Плательщика + +«RQ07999» Техническая ошибка + +Ошибки по методу GetQRCd + +Код Описание + +-1 Возникли проблемы при обработке запроса: <...> + +1 Внутренняя ошибка <...> + +3 Не заполнены данные: <...> + +8 Таймаут ответа, попробуйте позже + +26 Ошибка идентификации + +28 Запрос QR-кода не удался, не был получен Идентификатор QR-кода + +301 Некорректно заполнены данные данные: <...> + +100 Ошибка во время выполнения SQL-запроса для поиска AccountDR для TermNo= + +101 Ошибка во время выполнения SQL-запроса для проверки isUniQR для QrcId = + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Ошибки по методу GetQRCstatus + +Код Описание + +-1 Возникли проблемы при обработке запроса: <...> + +1 Внутренняя ошибка <...> + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 5/8 + + + +Код Описание + +2 Терминал <номер терминала> не обнаружен + +4 Не передан qrcId или payrrn + +5 Не получены данные от СПБ + +8 Таймаут ответа, попробуйте позже + +9 Ошибка идентификации, попробуйте позже + +16 Не передан параметр TermNo + +18 Платеж не найден в запросах B07,B23 <...> + +25 Терминал <номер терминала> заблокирован + +999* Неизвестная ошибка. Необходимо уточнить статус операции. + +Ошибки по методу GetQRCreversalData + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <текст с более подробным описанием ошибки> + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <текст с более подробным описанием ошибки> + +8 Таймаут ответа, попробуйте позже + +12 Не найдены данные для возврата + +16 Не передан параметр TermNo + +20 Получен отказ на запрос возврата. Статус <статус и при наличии код с текстом ошибки> + +21 Не удалось получить получателя перевода + +22 payrrn=<значение payrrn> в запросе не соответствует данным qrcId=<значение qrcId> у которого payrrn=<значение payrrn> + +23 Возврат невозможен для указанных параметров. Для payrrn=<значение payrrn> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +24 Возврат невозможен для указанных параметров. Для qrcId=<значение qrcId> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +25 Терминал <номер терминала> заблокирован + +27 Невозможно выполнить возврат по данному Терминалу, т.к. счёт зачисления не равен счёту списания + +29 Возврат невозможен. Для qrcId=<значение qrcId> не удалось найти успешный ответ на запрос GetQRCstatus + +40 Возврат невозможен. Для payrrn=<значение payrrn> не удалось найти успешный ответ на запрос GetQRCstatus + +1001 Превышено количество повторных запросов возврата B2C + +Ошибки по методу QRCreversal + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <текст с более подробным описанием ошибки> + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 6/8 + + + +Код Описание + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <текст с более подробным описанием ошибки> + +8 Таймаут ответа, попробуйте позже + +12 Не найдены данные для возврата + +13 Не найден успешный ответ на вызов GetQRCreversalData + +16 Не передан параметр TermNo + +20 Получен отказ на запрос возврата. Статус <статус и при наличии код с текстом ошибки> + +21 Не удалось получить получателя перевода + +22 payrrn=<значение payrrn> в запросе не соответствует данным qrcId=<значение qrcId> у которого payrrn=<значение payrrn> + +23 Возврат невозможен для указанных параметров. Для payrrn=<значение payrrn> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +24 Возврат невозможен для указанных параметров. Для qrcId=<значение qrcId> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +25 Терминал <номер терминала> заблокирован + +27 Невозможно выполнить возврат по данному Терминалу, т.к. счёт зачисления не равен счёту списания + +40 Возврат невозможен. Для payrrn=<значение payrrn> не удалось найти успешный ответ на запрос GetQRCstatus + +201 Получен отказ на запрос возврата. Статус <статус>, недостаточно средств на счёте + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Ошибки по методу ActivateCashQRc + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <...> + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <...> + +8 Таймаут ответа, попробуйте позже + +16 Не передан параметр TermNo + +25 Терминал <номер терминала> заблокирован + +28 Запрос QR-кода не удался, не был получен Идентификатор QR-кода + +41 При активации кассовой ссылки не удалось получить paramsId + +44 Кассовая ссылка зарегистрирована на устройстве #'<номер терминала>' и может быть использована только на этом устройстве + +301 Некорректно заполнены данные данные: <...> + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Коды ответов, направляемые в callback-уведомлении по сценарию «Оплата с привязанного счёта» по методу «resolution +/notification» + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 7/8 + + + +ErrorCode message + +«RQ05031» Отказ Банка Плательщика. Привязка счёта не найдена + +«RQ05032» Отказ Банка Плательщика в проведении платежа + +«RQ05060» Недостаточно денежных средств для проведения операции + +«RQ05061» Превышен лимит по сумме операций по СБП + +«RQ05062» Превышен лимит по количеству операций по СБП + +«RQ05063» Подозрение в мошенничестве + +«RQ05064» Выполнение операций в данной категории ТСП запрещено + +«RQ05065» Счёт заблокирован + +«RQ05066» Счёт закрыт + +«RQ05067» Выполнение операции запрещено по требованию законодательства + +Примечание: Применение кода ответа «RQ05032» допускается не более, чем в 20% от общего числа отказов со стороны Банка +Плательщика при выполнении Сценария «Оплата с привязанного счёта». + +Приложение 3. Пояснение для колонки «required» +«y» — «Yes» обязательное; + +«o» — «Optional» (опционально); + +«y/o» — «Условно обязательное» определяется условиями запроса. + +Приложение 4. Пояснение для колонки «Тип данных» + +Нотация Описание + +a Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8. + +n Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8. + +an Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8; + +Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8. + +ans Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8; + +Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8; + +Специальные символы с десятичными кодами из диапазонов [032-047], [058-064], [091-096], [123-126] в кодировке UTF-8; + +Символ «№» под номером 8470 в кодировке UTF-8. + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 8/8 + + diff --git a/_docs/laravel-libs/laravel-data/_index.md b/_docs/laravel-libs/laravel-data/_index.md new file mode 100644 index 0000000..3bc4445 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/_index.md @@ -0,0 +1,6 @@ +--- +title: v4 +slogan: Powerful data objects for Laravel +githubUrl: https://github.com/spatie/laravel-data +branch: main +--- diff --git a/_docs/laravel-libs/laravel-data/about-us.md b/_docs/laravel-libs/laravel-data/about-us.md new file mode 100644 index 0000000..8a137d1 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/about-us.md @@ -0,0 +1,11 @@ +--- +title: About us +weight: 9 +--- + +[Spatie](https://spatie.be) is a webdesign agency based in Antwerp, Belgium. + +Open source software is used in all projects we deliver. Laravel, Nginx, Ubuntu are just a few +of the free pieces of software we use every single day. For this, we are very grateful. +When we feel we have solved a problem in a way that can help other developers, +we release our code as open source software [on GitHub](https://spatie.be/open-source). diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/_index.md b/_docs/laravel-libs/laravel-data/advanced-usage/_index.md new file mode 100644 index 0000000..12ccdad --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/_index.md @@ -0,0 +1,4 @@ +--- +title: Advanced usage +weight: 5 +--- diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/available-property-mappers.md b/_docs/laravel-libs/laravel-data/advanced-usage/available-property-mappers.md new file mode 100644 index 0000000..b64704d --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/available-property-mappers.md @@ -0,0 +1,68 @@ +--- +title: Available property mappers +weight: 19 +--- + +In previous sections we've already seen how to [create](/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names) data objects where the keys of the +payload differ from the property names of the data object. It is also possible to [transform](/docs/laravel-data/v4/as-a-resource/mapping-property-names) data objects to an array/json/... where the keys of the payload differ +from the property names of the data object. + +These mappings can be set manually put the package also provide a set of mappers that can be used to automatically map +property names: + +```php +use Spatie\LaravelData\Mappers\CamelCaseMapper; +use Spatie\LaravelData\Mappers\SnakeCaseMapper; +use Spatie\LaravelData\Mappers\KebabCaseMapper; +use Spatie\LaravelData\Mappers\ProvidedNameMapper; +use Spatie\LaravelData\Mappers\StudlyCaseMapper; +use Spatie\LaravelData\Mappers\LowerCaseMapper; +use Spatie\LaravelData\Mappers\UpperCaseMapper; + +class ContractData extends Data +{ + public function __construct( + #[MapName(CamelCaseMapper::class)] + public string $name, + #[MapName(SnakeCaseMapper::class)] + public string $recordCompany, + #[MapName(KebabCaseMapper::class)] + public string $vatNumber, + #[MapName(new ProvidedNameMapper('country field'))] + public string $country, + #[MapName(StudlyCaseMapper::class)] + public string $cityName, + #[MapName(LowerCaseMapper::class)] + public string $addressLine1, + #[MapName(UpperCaseMapper::class)] + public string $addressLine2, + ) { + } +} +``` + +Creating the data object can now be done as such: + +```php +ContractData::from([ + 'name' => 'Rick Astley', + 'record_company' => 'RCA Records', + 'country field' => 'Belgium', + 'CityName' => 'Antwerp', + 'addressline1' => 'some address line 1', + 'ADDRESSLINE2' => 'some address line 2', +]); +``` + +When transforming such a data object the payload will look like this: + +```json +{ + "name" : "Rick Astley", + "record_company" : "RCA Records", + "country field" : "Belgium", + "CityName" : "Antwerp", + "addressline1" : "some address line 1", + "ADDRESSLINE2" : "some address line 2" +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/commands.md b/_docs/laravel-libs/laravel-data/advanced-usage/commands.md new file mode 100644 index 0000000..9e37e90 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/commands.md @@ -0,0 +1,45 @@ +--- +title: Commands +weight: 16 +--- + +## make:data + +You can easily generate new data objects with the artisan command `make:data`: + +```shell +php artisan make:data PostData +``` + +By default, this command puts data objects in the `App\Data` namespace, this can be changed as such: + +```shell +php artisan make:data PostData --namespace=DataTransferObjects +``` + +By default, the command creates a new data object within the `\App\Data` namespace and suffixes the class with `Data`, this can be changed by adding the following lines to the `data.php` config file: + +```php +'commands' => [ + /* + * Provides default configuration for the `make:data` command. These settings can be overridden with options + * passed directly to the `make:data` command for generating single Data classes, or if not set they will + * automatically fall back to these defaults. See `php artisan make:data --help` for more information + */ + 'make' => [ + /* + * The default namespace for generated Data classes. This exists under the application's root namespace, + * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the + * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. + */ + 'namespace' => 'Data', + + /* + * This suffix will be appended to all data classes generated by make:data, so that they are less likely + * to conflict with other related classes, controllers or models with a similar name without resorting + * to adding an alias for the Data object. Set to a blank string (not null) to disable. + */ + 'suffix' => 'Data', + ], +] +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-cast.md b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-cast.md new file mode 100644 index 0000000..5929c6b --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-cast.md @@ -0,0 +1,139 @@ +--- +title: Creating a cast +weight: 6 +--- + +Casts take simple values and cast them into complex types. For example, `16-05-1994T00:00:00+00` could be cast into a `Carbon` object with the same date. + +A cast implements the following interface: + +```php +interface Cast +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): mixed; +} +``` + +A cast receives the following: + +- **property** a `DataProperty` object which represents the property for which the value is cast. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures) +- **value** the value that should be cast +- **properties** an array of the current properties that will be used to create the data object +- **creationContext** the context in which the data object is being created you'll find the following info here: + - **dataClass** the data class which is being created + - **validationStrategy** the validation strategy which is being used + - **mapPropertyNames** whether property names should be mapped + - **disableMagicalCreation** whether to use the magical creation methods or not + - **ignoredMagicalMethods** the magical methods which are ignored + - **casts** a collection of global casts + +In the end, the cast should return a casted value. + +When the cast is unable to cast the value, an `Uncastable` object should be returned. + +## Null + +A cast like a transformer never receives a `null` value, this is because the package will always keep a `null` value as `null` because we don't want to create values out of thin air. If you want to replace a `null` value, then use a magic method. + +## Castables + +You may want to allow your application's value objects to define their own custom casting logic. Instead of attaching the custom cast class to your object, you may alternatively attach a value object class that implements the `Spatie\LaravelData\Casts\Castable` interface: + +```php +class ForgotPasswordRequest extends Data +{ + public function __construct( + #[WithCastable(Email::class)] + public Email $email, + ) { + } +} +``` + +When using `Castable` classes, you may still provide arguments in the `WithCastable` attribute. The arguments will be passed to the `dataCastUsing` method: + +```php +class DuplicateEmailCheck extends Data +{ + public function __construct( + #[WithCastable(Email::class, normalize: true)] + public Email $email, + ) { + } +} +``` + +By combining "castables" with PHP's [anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php), you may define a value object and its casting logic as a single castable object. To accomplish this, return an anonymous class from your value object's `dataCastUsing` method. The anonymous class should implement the `Cast` interface: + +```php +type` to get the type the items should be transformed into. + +## Combining casts and transformers + +You can combine casts and transformers in one class: + +```php +class ToUpperCastAndTransformer implements Cast, Transformer +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): string + { + return strtoupper($value); + } + + public function transform(DataProperty $property, mixed $value, TransformationContext $context): string + { + return strtoupper($value); + } +} +``` + +Within your data object, you can use the `WithCastAndTransformer` attribute to use the cast and transformer: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[WithCastAndTransformer(SomeCastAndTransformer::class)] + public string $artist, + ) { + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-rule-inferrer.md b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-rule-inferrer.md new file mode 100644 index 0000000..be6cfa2 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-rule-inferrer.md @@ -0,0 +1,63 @@ +--- +title: Creating a rule inferrer +weight: 8 +--- + +Rule inferrers will try to infer validation rules for properties within a data object. + +A rule inferrer can be created by implementing the `RuleInferrer` interface: + +```php +interface RuleInferrer +{ + public function handle(DataProperty $property, PropertyRules $rules, ValidationContext $context): PropertyRules; +} +``` + +A collection of previous inferred rules is given, and a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures). + +The `ValidationContext` is also injected, this contains the following info: + +- **payload** the current payload respective to the data object which is being validated +- **fullPayload** the full payload which is being validated +- **validationPath** the path from the full payload to the current payload + +The `RulesCollection` contains all the rules for the property represented as `ValidationRule` objects. + +You can add new rules to it: + +```php +$rules->add(new Min(42)); +``` + +When adding a rule of the same kind, a previous version of the rule will be removed: + +```php +$rules->add(new Min(42)); +$rules->add(new Min(314)); + +$rules->all(); // [new Min(314)] +``` + +Adding a string rule can be done as such: + +```php +$rules->add(new Rule('min:42')); +``` + +You can check if the collection contains a type of rule: + +```php +$rules->hasType(Min::class); +``` + +Or remove certain types of rules: + +```php +$rules->removeType(Min::class); +``` + +In the end, a rule inferrer should always return a `RulesCollection`. + +Rule inferrers need to be manually defined within the `data.php` config file. + diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-transformer.md b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-transformer.md new file mode 100644 index 0000000..7555958 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/creating-a-transformer.md @@ -0,0 +1,60 @@ +--- +title: Creating a transformer +weight: 7 +--- + +Transformers take complex values and transform them into simple types. For example, a `Carbon` object could be transformed to `16-05-1994T00:00:00+00`. + +A transformer implements the following interface: + +```php +interface Transformer +{ + public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed; +} +``` + +The following parameters are provided: + +- **property**: a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures) +- **value**: the value that should be transformed, this will never be `null` +- **context**: a `TransformationContext` object which contains the current transformation context with the following properties: + - **transformValues** indicates if values should be transformed or not + - **mapPropertyNames** indicates if property names should be mapped or not + - **wrapExecutionType** the execution type that should be used for wrapping values + - **transformers** a collection of transformers that can be used to transform values + +In the end, the transformer should return a transformed value. + +## Combining transformers and casts + +You can transformers and casts in one class: + +```php +class ToUpperCastAndTransformer implements Cast, Transformer +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): string + { + return strtoupper($value); + } + + public function transform(DataProperty $property, mixed $value, TransformationContext $context): string + { + return strtoupper($value); + } +} +``` + +Within your data object, you can use the `WithCastAndTransformer` attribute to use the cast and transformer: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[WithCastAndTransformer(SomeCastAndTransformer::class)] + public string $artist, + ) { + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/eloquent-casting.md b/_docs/laravel-libs/laravel-data/advanced-usage/eloquent-casting.md new file mode 100644 index 0000000..56f3aca --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/eloquent-casting.md @@ -0,0 +1,246 @@ +--- +title: Eloquent casting +weight: 1 +--- + +Since data objects can be created from arrays and be easily transformed into arrays back again, they are excellent to be used +with [Eloquent casts](https://laravel.com/docs/eloquent-mutators#custom-casts): + +```php +class Song extends Model +{ + protected $casts = [ + 'artist' => ArtistData::class, + ]; +} +``` + +Now you can store a data object in a model as such: + +```php +Song::create([ + 'artist' => new ArtistData(name: 'Rick Astley', age: 22), +]); +``` + +It is also possible to use an array representation of the data object: + +```php +Song::create([ + 'artist' => [ + 'name' => 'Rick Astley', + 'age' => 22 + ] +]); +``` + +This will internally be converted to a data object which you can later retrieve as such: + +```php +Song::findOrFail($id)->artist; // ArtistData object +``` + +### Abstract data objects + +Sometimes you have an abstract parent data object with multiple child data objects, for example: + +```php +abstract class RecordConfig extends Data +{ + public function __construct( + public int $tracks, + ) {} +} + +class CdRecordConfig extends RecordConfig +{ + public function __construct( + int $tracks, + public int $bytes, + ) { + parent::__construct($tracks); + } +} + +class VinylRecordConfig extends RecordConfig +{ + public function __construct( + int $tracks, + public int $rpm, + ) { + parent::__construct($tracks); + } +} +``` + +A model can have a JSON field which is either one of these data objects: + +```php +class Record extends Model +{ + protected $casts = [ + 'config' => RecordConfig::class, + ]; +} +``` + +You can then store either a `CdRecordConfig` or a `VinylRecord` in the `config` field: + +```php +$cdRecord = Record::create([ + 'config' => new CdRecordConfig(tracks: 12, bytes: 1000), +]); + +$vinylRecord = Record::create([ + 'config' => new VinylRecordConfig(tracks: 12, rpm: 33), +]); + +$cdRecord->config; // CdRecordConfig object +$vinylRecord->config; // VinylRecordConfig object +``` + +When a data object class is abstract and used as an Eloquent cast, then this feature will work out of the box. + +The child data object value of the model will be stored in the database as a JSON string with the class name and the data object properties: + +```json +{ + "type": "\\App\\Data\\CdRecordConfig", + "data": { + "tracks": 12, + "bytes": 1000 + } +} +``` + +When retrieving the model, the data object will be instantiated based on the `type` key in the JSON string. + +#### Abstract data object with collection + +You can use with collection. + +```php +class Record extends Model +{ + protected $casts = [ + 'configs' => DataCollection::class . ':' . RecordConfig::class, + ]; +} +``` + +#### Abstract data class morphs + +By default, the `type` key in the JSON string will be the fully qualified class name of the child data object. This can break your application quite easily when you refactor your code. To prevent this, you can add a morph map like with [Eloquent models](https://laravel.com/docs/eloquent-relationships#polymorphic-relationships). Within your `AppServiceProvivder` you can add the following mapping: + +```php +use Spatie\LaravelData\Support\DataConfig; + +app(DataConfig::class)->enforceMorphMap([ + 'cd_record_config' => CdRecordConfig::class, + 'vinyl_record_config' => VinylRecordConfig::class, +]); +``` + +## Casting data collections + +It is also possible to store data collections in an Eloquent model: + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class, + ]; +} +``` + +A collection of data objects within the Eloquent model can be made as such: + +```php +Artist::create([ + 'songs' => [ + new SongData(title: 'Never gonna give you up', artist: 'Rick Astley'), + new SongData(title: 'Together Forever', artist: 'Rick Astley'), + ], +]); +``` + +It is also possible to provide an array instead of a data object to the collection: + +```php +Artist::create([ + 'songs' => [ + ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley'], + ['title' => 'Together Forever', 'artist' => 'Rick Astley'] + ], +]); +``` + +## Using defaults for null database values + +By default, if a database value is `null`, then the model attribute will also be `null`. However, sometimes you might want to instantiate the attribute with some default values. + +To achieve this, you may provide an additional `default` [Cast Parameter](https://laravel.com/docs/eloquent-mutators#cast-parameters) to ensure the caster gets instantiated. + +```php +class Song extends Model +{ + protected $casts = [ + 'artist' => ArtistData::class . ':default', + ]; +} +``` + +This will ensure that the `ArtistData` caster is instantiated even when the `artist` attribute in the database is `null`. + +You may then specify some default values in the cast which will be used instead. + +```php +class ArtistData extends Data +{ + public string $name = 'Default name'; +} +``` + +```php +Song::findOrFail($id)->artist->name; // 'Default name' +``` + +### Nullable collections + +You can also use the `default` argument in the case where you _always_ want a `DataCollection` to be returned. + +The first argument (after `:`) should always be the data class to be used with the `DataCollection`, but you can add `default` as a comma separated second argument. + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class.',default', + ]; +} +``` + +```php +$artist = Artist::create([ + 'songs' => null +]); + +$artist->songs; // DataCollection +$artist->songs->count();// 0 +``` + +## Using encryption with data objects and collections + +Similar to Laravel's native encrypted casts, you can also encrypt data objects and collections. + +When retrieving the model, the data object will be decrypted automatically. + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class.',encrypted', + ]; +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/get-data-from-a-class-quickly.md b/_docs/laravel-libs/laravel-data/advanced-usage/get-data-from-a-class-quickly.md new file mode 100644 index 0000000..b04de97 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/get-data-from-a-class-quickly.md @@ -0,0 +1,55 @@ +--- +title: Get data from a class quickly +weight: 15 +--- + +By adding the `WithData` trait to a Model, Request or any class that can be magically be converted to a data object, +you'll enable support for the `getData` method. This method will automatically generate a data object for the object it +is called upon. + +For example, let's retake a look at the `Song` model we saw earlier. We can add the `WithData` trait as follows: + +```php +class Song extends Model +{ + use WithData; + + protected $dataClass = SongData::class; +} +``` + +Now we can quickly get the data object for the model as such: + +```php +Song::firstOrFail($id)->getData(); // A SongData object +``` + +We can do the same with a FormRequest, we don't use a property here to define the data class but use a method instead: + +```php +class SongRequest extends FormRequest +{ + use WithData; + + protected function dataClass(): string + { + return SongData::class; + } +} +``` + +Now within a controller where the request is injected, we can get the data object like this: + +```php +class SongController +{ + public function __invoke(SongRequest $request): SongData + { + $data = $request->getData(); + + $song = Song::create($data->toArray()); + + return $data; + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/in-packages.md b/_docs/laravel-libs/laravel-data/advanced-usage/in-packages.md new file mode 100644 index 0000000..71fa68e --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/in-packages.md @@ -0,0 +1,23 @@ +--- +title: In Packages +weight: 18 +--- + +## Testing + +When you're developing a package, running into config access issues is quite common, especially when using the magic from factory method, which won't resolve the factory instance without the config. Simply include our Provider in your package's TestCase, and you're all set. + +```php +use Orchestra\Testbench\TestCase as Orchestra; + +class TestCase extends Orchestra +{ + protected function getPackageProviders($app) + { + return [ + LaravelDataServiceProvider::class, + // Register additional service providers to use with your tests + ]; + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/internal-structures.md b/_docs/laravel-libs/laravel-data/advanced-usage/internal-structures.md new file mode 100644 index 0000000..27a4a74 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/internal-structures.md @@ -0,0 +1,126 @@ +--- +title: Internal structures +weight: 11 +--- + +This package has some internal structures which are used to analyze data objects and their properties. They can be +helpful when writing casts, transformers or rule inferrers. + +## DataClass + +The DataClass represents the structure of a data object and has the following properties: + +- `name` the name of the data class +- `properties` all the `DataProperty`'s of the class (more on that later) +- `methods` all the magical creation `DataMethod`s of the class (more on that later) +- `constructorMethod` the constructor `DataMethod` of the class +- `isReadOnly` is the class read only +- `isAbstract` is the class abstract +- `appendable` is the class implementing `AppendableData` +- `includeable` is the class implementing `IncludeableData` +- `responsable` is the class implementing `ResponsableData` +- `transformable` is the class implementing `TransformableData` +- `validatable` is the class implementing `ValidatableData` +- `wrappable` is the class implementing `WrappableData` +- `emptyData` the the class implementing `EmptyData` +- `attributes` a collection of resolved attributes assigned to the class +- `dataCollectablePropertyAnnotations` the property annotations of the class used to infer the data collection type +- `allowedRequestIncludes` the allowed request includes of the class +- `allowedRequestExcludes` the allowed request excludes of the class +- `allowedRequestOnly` the allowed request only of the class +- `allowedRequestExcept` the allowed request except of the class +- `outputMappedProperties` properties names which are mapped when transforming the data object +- `transformationFields` structure of the transformation fields + +## DataProperty + +A data property represents a single property within a data object. + +- `name` the name of the property +- `className` the name of the class of the property +- `type` the `DataPropertyType` of the property (more on that later) +- `validate` should the property be automatically validated +- `computed` is the property computed +- `hidden` will the property be hidden when transforming the data object +- `isPromoted` is the property constructor promoted +- `isReadOnly` is the property read only +- `hasDefaultValue` has the property a default value +- `defaultValue` the default value of the property +- `cast` the cast assigned to the property +- `transformer` the transformer assigned to the property +- `inputMappedName` the name used to map a property name given +- `outputMappedName` the name used to map a property name onto +- `attributes` a collection of resolved attributes assigned to the property + +## DataMethod + +A data method represents a method within a data object. + +- `name` the name of the method +- `parameters` all the `DataParameter`'s and `DataProperty`s of the method (more on that later) +- `isStatic` whether the method is static +- `isPublic` whether the method is public +- `isCustomCreationMethod` whether the method is a custom creation method (=magical creation method) +- `returnType` the `DataType` of the return value (more on that later) + +## DataParameter + +A data parameter represents a single parameter/property within a data method. + +- `name` the name of the parameter +- `isPromoted` is the property/parameter constructor promoted +- `hasDefaultValue` has the parameter a default value +- `defaultValue` the default value of the parameter +- `type` the `DataType` of the parameter (more on that later) + +## DataType + +A data type represents a type within a data object. + +- `Type` can be a `NamedType`, `UnionType` or `IntersectionType` (more on that later) +- `isNullable` can the type be nullable +- `isMixed` is the type a mixed type +- `kind` the `DataTypeKind` of the type (more on that later) + +## DataPropertyType + +Extends from the `DataType` and has the following additional properties: + +- `isOptional` can the type be optional +- `lazyType` the class of the lazy type for the property +- `dataClass` the data object class of the property or the data object class of the collection it collects +- `dataCollectableClass` the collectable type of the data objects +- `kind` the `DataTypeKind` of the type (more on that later) + +## DataTypeKind + +An enum representing the kind of type of a property/parameter with respect to the package: + +- Default: a non package specific type +- DataObject: a data object +- DataCollection: a `DataCollection` of data objects +- DataPaginatedCollection: a `DataPaginatedCollection` of data objects +- DataCursorPaginatedCollection: a `DataCursorPaginatedCollection` of data objects +- DataArray: an array of data objects +- DataEnumerable: a `Enumerable` of data objects +- DataPaginator: a `Paginator` of data objects +- DataCursorPaginator: a `CursorPaginator` of data objects + +## NamedType + +Represents a named PHP type with the following properties: + +- `name` the name of the type +- `builtIn` is the type a built-in type +- `acceptedTypes` an array of accepted types as string +- `kind` the `DataTypeKind` of the type (more on that later) +- `dataClass` the data object class of the property or the data object class of the collection it collects +- `dataCollectableClass` the collectable type of the data objects +- `isCastable` wetter the type is a `Castable` + +## UnionType / IntersectionType + +Represents a union or intersection of types with the following properties: + +- `types` an array of types (can be `NamedType`, `UnionType` or `IntersectionType`) + diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/mapping-rules.md b/_docs/laravel-libs/laravel-data/advanced-usage/mapping-rules.md new file mode 100644 index 0000000..33c3f93 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/mapping-rules.md @@ -0,0 +1,72 @@ +--- +title: Mapping rules +weight: 13 +--- + +It is possible to map the names properties going in and out of your data objects using: `MapOutputName`, `MapInputName` +and `MapName` attributes. But sometimes it can be quite hard to follow where which name can be used. Let's go through +some case: + +In the data object: + +```php +class UserData extends Data + { + public function __construct( + #[MapName('favorite_song')] // name mapping + public Lazy|SongData $song, + #[RequiredWith('song')] // In validation rules, use the original name + public string $title, + ) { + } + + public static function allowedRequestExcept(): ?array + { + return [ + 'song', // Use the original name when defining includes, excludes, excepts and only + ]; + } + + public function rules(ValidContext $context): array { + return [ + 'song' => 'required', // Use the original name when defining validation rules + ]; + } + + // ... + } + ``` + +When creating a data object: + +```php +UserData::from([ + 'favorite_song' => ..., // You can use the mapped or original name here + 'title' => 'some title' +]); +``` + +When adding an include, exclude, except or only: + +```php + UserData::from(User::first())->except('song'); // Always use the original name here +``` + +Within a request query, you can use the mapped or original name: + +``` +https://spatie.be/my-account?except[]=favorite_song +``` + +When validating a data object or getting rules for a data object, always use the original name: + +```php +$data = [ + 'favorite_song' => 123, + 'title' => 'some title', +]; + +UserData::validate($data) +UserData::getValidationRules($data) +``` + diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/normalizers.md b/_docs/laravel-libs/laravel-data/advanced-usage/normalizers.md new file mode 100644 index 0000000..5b9006b --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/normalizers.md @@ -0,0 +1,66 @@ +--- +title: Normalizers +weight: 4 +--- + +This package allows you to dynamically create data objects from any kind of object. For example, you can use an +eloquent model to create a data object like this: + +```php +SongData::from(Song::findOrFail($id)); +``` + +A `Normalizer` will take a payload like a model and will transform it into an array, so it can be used in the pipeline (see further). + +By default, there are five normalizers: + +- **ModelNormalizer** will cast eloquent models +- **ArrayableNormalizer** will cast `Arrayable`'s +- **ObjectNormalizer** will cast `stdObject`'s +- **ArrayNormalizer** will cast arrays +- **JsonNormalizer** will cast json strings + +A sixth normalizer can be optionally enabled: + +- **FormRequestNormalizer** will normalize a form request by calling the `validated` method + +Normalizers can be globally configured in `config/data.php`, and can be configured on a specific data object by overriding the `normalizers` method. + +```php +class SongData extends Data +{ + public function __construct( + // ... + ) { + } + + public static function normalizers(): array + { + return [ + ModelNormalizer::class, + ArrayableNormalizer::class, + ObjectNormalizer::class, + ArrayNormalizer::class, + JsonNormalizer::class, + ]; + } +} +``` + +A normalizer implements the `Normalizer` interface and should return an array representation of the payload, or null if it cannot normalize the payload: + +```php +class ArrayableNormalizer implements Normalizer +{ + public function normalize(mixed $value): ?array + { + if (! $value instanceof Arrayable) { + return null; + } + + return $value->toArray(); + } +} +``` + +Normalizers are executed in the same order as they are defined in the `normalize` method. The first normalizer not returning null will be used to normalize the payload. Magical creation methods always have precedence over normalizers. diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/performance.md b/_docs/laravel-libs/laravel-data/advanced-usage/performance.md new file mode 100644 index 0000000..d1efe69 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/performance.md @@ -0,0 +1,88 @@ +--- +title: Performance +weight: 15 +--- + +Laravel Data is a powerful package that leverages PHP reflection to infer as much information as possible. While this approach provides a lot of benefits, it does come with a minor performance overhead. This overhead is typically negligible during development, but it can become noticeable in a production environment with a large number of data objects. + +Fortunately, Laravel Data is designed to operate efficiently without relying on reflection. It achieves this by allowing you to cache the results of its complex analysis. This means that the performance cost is incurred only once, rather than on every request. By caching the analysis results before deploying your application to production, you ensure that a pre-analyzed, cached version of the data objects is used, significantly improving performance. + +## Caching + +Laravel Data provides a command to cache the analysis results of your data objects. This command will analyze all of your data objects and store the results in a Laravel cache of your choice: + +``` +php artisan data:cache-structures +``` + +That's it, the command will search for all the data objects in your application and cache the analysis results. Be sure to always run this command after creating or modifying a data object or when deploying your application to production. + +## Configuration + +The caching mechanism can be configured in the `data.php` config file. By default, the cache store is set to the default cache store of your application. You can change this to any other cache driver supported by Laravel. A prefix can also be set for the cache keys stored: + +```php +'structure_caching' => [ + 'cache' => [ + 'store' => 'redis', + 'prefix' => 'laravel-data', + ], +], +``` + +To find the data classes within your application, we're using the [php-structure-discoverer](https://github.com/spatie/php-structure-discoverer) package. This package allows you to configure the directories that will be searched for data objects. By default, the `app/data` directory is searched recursively. You can change this to any other directory or directories: + +```php +'structure_caching' => [ + 'directories' => [ + app_path('Data'), + ], +], +``` + +Structure discoverer uses reflection (enabled by default) or a PHP parser to find the data objects. You can disable the reflection-based discovery and thus use the PHP parser discovery as such: + +```php +'structure_caching' => [ + 'reflection_discovery' => [ + 'enabled' => false, + ], +], +``` + +Since we cannot depend on reflection, we need to tell the parser what data objects are exactly and where to find them. This can be done by adding the laravel-data directory to the config directories: + +```php +'structure_caching' => [ + 'directories' => [ + app_path('Data'), + base_path('vendor/spatie/laravel-data/src'), + ], +], +``` + +When using reflection discovery, the base directory and root namespace can be configured as such if you're using a non-standard directory structure or namespace + +```php +'structure_caching' => [ + 'reflection_discovery' => [ + 'enabled' => true, + 'base_path' => base_path(), + 'root_namespace' => null, + ], +], +``` + +The caching mechanism can be disabled by setting the `enabled` option to `false`: + +```php +'structure_caching' => [ + 'enabled' => false, +], +``` + +You can read more about reflection discovery [here](https://github.com/spatie/php-structure-discoverer#parsers). + +## Testing + +When running tests, the cache is automatically disabled. This ensures that the analysis results are always up-to-date during development and testing. And that the cache won't interfere with your caching mocks. diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/pipeline.md b/_docs/laravel-libs/laravel-data/advanced-usage/pipeline.md new file mode 100644 index 0000000..e2aec83 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/pipeline.md @@ -0,0 +1,125 @@ +--- +title: Pipeline +weight: 5 +--- + +The data pipeline allows you to configure how data objects are constructed from a payload. In the previous chapter we +saw that a data object created from a payload will be first normalized into an array. This array is passed into the +pipeline. + +The pipeline exists of multiple pipes which will transform the normalized data into a collection of property values +which can be passed to the data object constructor. + +By default, the pipeline exists of the following pipes: + +- **AuthorizedDataPipe** checks if the user is authorized to perform the request +- **MapPropertiesDataPipe** maps the names of properties +- **FillRouteParameterPropertiesDataPipe** fills property values from route parameters +- **ValidatePropertiesDataPipe** validates the properties +- **DefaultValuesDataPipe** adds default values for properties when they are not set +- **CastPropertiesDataPipe** casts the values of properties + +Each result of the previous pipe is passed on into the next pipe, you can define the pipes on an individual data object +as such: + +```php +class SongData extends Data +{ + public function __construct( + // ... + ) { + } + + public static function pipeline(): DataPipeline + { + return DataPipeline::create() + ->into(static::class) + ->through(AuthorizedDataPipe::class) + ->through(MapPropertiesDataPipe::class) + ->through(FillRouteParameterPropertiesDataPipe::class) + ->through(ValidatePropertiesDataPipe::class) + ->through(DefaultValuesDataPipe::class) + ->through(CastPropertiesDataPipe::class); + } +} +``` + +Each pipe implements the `DataPipe` interface and should return an `array` of properties: + +```php +interface DataPipe +{ + public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array; +} +``` + +The `handle` method has several arguments: + +- **payload** the non normalized payload +- **class** the `DataClass` object for the data + object [more info](/docs/laravel-data/v4/advanced-usage/internal-structures) +- **properties** the key-value properties which will be used to construct the data object +- **creationContext** the context in which the data object is being created you'll find the following info here: + - **dataClass** the data class which is being created + - **validationStrategy** the validation strategy which is being used + - **mapPropertyNames** whether property names should be mapped + - **disableMagicalCreation** whether to use the magical creation methods or not + - **ignoredMagicalMethods** the magical methods which are ignored + - **casts** a collection of global casts + +When using a magic creation methods, the pipeline is not being used (since you manually overwrite how a data object is +constructed). Only when you pass in a request object a minimal version of the pipeline is used to authorize and validate +the request. + +## Preparing data for the pipeline + +Sometimes you need to make some changes to the payload after it has been normalized, but before they are sent into the data pipeline. You can do this using the `prepareForPipeline` method as follows: + +```php +class SongMetadata +{ + public function __construct( + public string $releaseYear, + public string $producer, + ) {} +} + +class SongData extends Data +{ + public function __construct( + public string $title, + public SongMetadata $metadata, + ) {} + + public static function prepareForPipeline(array $properties): array + { + $properties['metadata'] = Arr::only($properties, ['release_year', 'producer']); + + return $properties; + } +} +``` + +Now it is possible to create a data object as follows: + +```php +$songData = SongData::from([ + 'title' => 'Never gonna give you up', + 'release_year' => '1987', + 'producer' => 'Stock Aitken Waterman', +]); +``` + +## Extending the pipeline within your data class + +Sometimes you want to send your payload first through a certain pipe without creating a whole new pipeline, this can be done as such: + +```php +class SongData extends Data +{ + public static function pipeline(): DataPipeline + { + return parent::pipeline()->firstThrough(GuessCasingForKeyDataPipe::class); + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/traits-and-interfaces.md b/_docs/laravel-libs/laravel-data/advanced-usage/traits-and-interfaces.md new file mode 100644 index 0000000..b6a02e8 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/traits-and-interfaces.md @@ -0,0 +1,60 @@ +--- +title: Traits and interfaces +weight: 17 +--- + +Laravel data, is built to be as flexible as possible. This means that you can use it in any way you want. + +For example, the `Data` class we've been using throughout these docs is a class implementing a few data interfaces and traits: + +```php +use Illuminate\Contracts\Support\Responsable; +use Spatie\LaravelData\Concerns\AppendableData; +use Spatie\LaravelData\Concerns\BaseData; +use Spatie\LaravelData\Concerns\ContextableData; +use Spatie\LaravelData\Concerns\EmptyData; +use Spatie\LaravelData\Concerns\IncludeableData; +use Spatie\LaravelData\Concerns\ResponsableData; +use Spatie\LaravelData\Concerns\TransformableData; +use Spatie\LaravelData\Concerns\ValidateableData; +use Spatie\LaravelData\Concerns\WrappableData; +use Spatie\LaravelData\Contracts\AppendableData as AppendableDataContract; +use Spatie\LaravelData\Contracts\BaseData as BaseDataContract; +use Spatie\LaravelData\Contracts\EmptyData as EmptyDataContract; +use Spatie\LaravelData\Contracts\IncludeableData as IncludeableDataContract; +use Spatie\LaravelData\Contracts\ResponsableData as ResponsableDataContract; +use Spatie\LaravelData\Contracts\TransformableData as TransformableDataContract; +use Spatie\LaravelData\Contracts\ValidateableData as ValidateableDataContract; +use Spatie\LaravelData\Contracts\WrappableData as WrappableDataContract; + +abstract class Data implements Responsable, AppendableDataContract, BaseDataContract, TransformableDataContract, IncludeableDataContract, ResponsableDataContract, ValidateableDataContract, WrappableDataContract, EmptyDataContract +{ + use ResponsableData; + use IncludeableData; + use AppendableData; + use ValidateableData; + use WrappableData; + use TransformableData; + use BaseData; + use EmptyData; + use ContextableData; +} +``` + +These traits and interfaces allow you to create your own versions of the base `Data` class, and add your own functionality to it. + +An example of such custom base data classes are the `Resource` and `Dto` class. + +Each interface (and corresponding trait) provides a piece of functionality: + +- **BaseData** provides the base functionality of the data package to create data objects +- **BaseDataCollectable** provides the base functionality of the data package to create data collections +- **ContextableData** provides the functionality to add context for includes and wraps to the data object/collectable +- **IncludeableData** provides the functionality to add includes, excludes, only and except to the data object/collectable +- **TransformableData** provides the functionality to transform the data object/collectable +- **ResponsableData** provides the functionality to return the data object/collectable as a response +- **WrappableData** provides the functionality to wrap the transformed data object/collectable +- **AppendableData** provides the functionality to append data to the transformed data payload +- **EmptyData** provides the functionality to get an empty version of the data object +- **ValidateableData** provides the functionality to validate the data object +- **DeprecatableData** provides the functionality to add deprecated functionality to the data object diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/typescript.md b/_docs/laravel-libs/laravel-data/advanced-usage/typescript.md new file mode 100644 index 0000000..08de760 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/typescript.md @@ -0,0 +1,130 @@ +--- +title: Transforming to TypeScript +weight: 2 +--- + +Thanks to the [typescript-transformer](https://spatie.be/docs/typescript-transformer) package, it is possible to +automatically transform data objects into TypeScript definitions. + +For example, the following data object: + +```php +class DataObject extends Data +{ + public function __construct( + public null|int $nullable, + public int $int, + public bool $bool, + public string $string, + public float $float, + /** @var string[] */ + public array $array, + public Lazy|string $lazy, + public Optional|string $optional, + public SimpleData $simpleData, + /** @var \Spatie\LaravelData\Tests\Fakes\SimpleData[] */ + public DataCollection $dataCollection, + ) + { + } +} +``` + +... can be transformed to the following TypeScript type: + +```tsx +{ + nullable: number | null; + int: number; + bool: boolean; + string: string; + float: number; + array: Array; + lazy? : string; + optional? : string; + simpleData: SimpleData; + dataCollection: Array; +} +``` + +## Installation of extra package + +First, you must install the spatie/laravel-typescript-transformer into your project. + +```bash +composer require spatie/laravel-typescript-transformer +``` + +Next, publish the config file of the typescript-transformer package with: + +```bash +php artisan vendor:publish --tag=typescript-transformer-config +``` + +Finally, add the `Spatie\LaravelData\Support\TypeScriptTransformer\DataTypeScriptTransformer` transformer to the +transformers in the `typescript-transformer.php` config file. + +If you're using the `DtoTransformer` provided by the package, then be sure to put the `DataTypeScriptTransformer` before the `DtoTransformer`. + +## Usage + +Annotate each data object that you want to transform to Typescript with a `/** @typescript */` annotation or +a `#[TypeScript]` attribute. + +To [generate the typescript file](https://spatie.be/docs/typescript-transformer/v4/laravel/executing-the-transform-command) +, run this command: + +```php +php artisan typescript:transform +``` + +If you want to transform all the data objects within your application to TypeScript, you can use +the `DataTypeScriptCollector`, which should be added to the collectors in `typescript-transformer.php`. + +If you're using the `DefaultCollector` provided by the package, then be sure to put the `DataTypeScriptCollector` before the `DefaultCollector`. + +### Optional types + +An optional or lazy property will automatically be transformed into an optional type within TypeScript: + +```php +class DataObject extends Data +{ + public function __construct( + public Lazy|string $lazy, + public Optional|string $optional, + ) + { + } +} +``` + +This will be transformed into: + +```tsx +{ + lazy? : string; + optional? : string; +} +``` + +If you want to have optional typed properties in TypeScript without typing your properties optional or lazy within PHP, +then you can use the `Optional` attribute from the `typescript-transformer` package. + +Don't forget to alias it as `TypeScriptOptional` when you're already using this package's `Optional` type! + +```php +use Spatie\TypeScriptTransformer\Attributes\Optional as TypeScriptOptional; + +class DataObject extends Data +{ + public function __construct( + #[TypeScriptOptional] + public int $id, + public string $someString, + public Optional|string $optional, + ) + { + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/use-with-inertia.md b/_docs/laravel-libs/laravel-data/advanced-usage/use-with-inertia.md new file mode 100644 index 0000000..4f6ca1d --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/use-with-inertia.md @@ -0,0 +1,149 @@ +--- +title: Use with Inertia +weight: 9 +--- + +> Inertia.js lets you quickly build modern single-page React, Vue, and Svelte apps using classic server-side routing and +> controllers. + +Laravel Data works excellent with [Inertia](https://inertiajs.com). + +You can pass a complete data object to an Inertia response: + +```php +return Inertia::render('Song', SongsData::from($song)); +``` + +## Lazy properties + +This package supports [lazy](https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties) properties, which can +be manually included or excluded. + +Inertia has a similar concept called [lazy data evaluation](https://inertiajs.com/partial-reloads#lazy-data-evaluation), +where some properties wrapped in a closure only get evaluated and included in the response when explicitly asked. +Inertia v2 introduced the concept of [deferred props](https://inertiajs.com/deferred-props), which allows to defer the +loading of certain data until after the initial page render. + +This package can output specific properties as Inertia lazy or deferred props as such: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + public Lazy|string $lyrics, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::inertia(fn() => $song->title), + Lazy::closure(fn() => $song->artist) + Lazy::inertiaDeferred(fn() => $song->lyrics) + ); + } +} +``` + +We provide three kinds of lazy properties: + +- **Lazy::inertia()** Never included on first visit, optionally included on partial reloads +- **Lazy::closure()** Always included on first visit, optionally included on partial reloads +- **Lazy::inertiaDeferred()** Included when ready, optionally included on partial reloads + +Now within your JavaScript code, you can include the properties as such: + +```js +router.reload((url, { + only: ['title'], +}); +``` + +#### Deferred property groups + +It is possible to group deferred properties together, so that all grouped properties are loaded at the same time. In +order to achieve this, you can pass a group name as the second argument to `Lazy::inertiaDeferred()`: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + public Lazy|string $lyrics, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::inertiaDeferred(fn() => $song->title), + Lazy::inertiaDeferred(fn() => $song->artist, 'details') + Lazy::inertiaDeferred(fn() => $song->lyrics, 'details') + ); + } +} +``` + +### Auto lazy Inertia properties + +We already saw earlier that the package can automatically make properties Lazy, the same can be done for Inertia +properties. + +It is possible to rewrite the previous example as follows: + +```php +use Spatie\LaravelData\Attributes\AutoClosureLazy; +use Spatie\LaravelData\Attributes\AutoInertiaLazy; +use Spatie\LaravelData\Attributes\AutoInertiaDeferred; + +class SongData extends Data +{ + public function __construct( + #[AutoInertiaLazy] + public Lazy|string $title, + #[AutoClosureLazy] + public Lazy|string $artist, + #[AutoInertiaDeferred] + public Lazy|string $lyrics, + ) { + } +} +``` + +If all the properties of a class should be either Inertia or closure lazy, you can use the attributes on the class +level: + +```php +#[AutoInertiaLazy] +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + ) { + } +} +``` + +#### Deferred property groups + +For the `AutoInertiaDeferred` attribute, it is also possible to specify a group name in order to group deferred +properties together: + +```php +class SongData extends Data +{ + public function __construct( + #[AutoInertiaDeferred()] + public Lazy|string $title, + #[AutoInertiaDeferred('details')] + public Lazy|string $artist, + #[AutoInertiaDeferred('details')] + public Lazy|string $lyrics, + ) { + } +} +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/use-with-livewire.md b/_docs/laravel-libs/laravel-data/advanced-usage/use-with-livewire.md new file mode 100644 index 0000000..43279d4 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/use-with-livewire.md @@ -0,0 +1,131 @@ +--- +title: Use with Livewire +weight: 10 +--- + +> Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple without leaving the +> comfort of Laravel. + +Laravel Data works excellently with [Laravel Livewire](https://laravel-livewire.com). + +You can use a data object as one of the properties of your Livewire component as such: + +```php +class Song extends Component +{ + public SongData $song; + + public function mount(int $id) + { + $this->song = SongData::from(Song::findOrFail($id)); + } + + public function render() + { + return view('livewire.song'); + } +} +``` + +A few things are required to make this work: + +1) You should implement `Wireable` on all the data classes you'll be using with Livewire +2) Each of these classes should also use the `WireableData` trait provided by this package +3) That's it + +We can update our previous example to make it work with Livewire as such: + +```php +class SongData extends Data implements Wireable +{ + use WireableData; + + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +## Livewire Synths (Experimental) + +Laravel Data also provides a way to use Livewire Synths with your data objects. It will allow you to use data objects +and collections +without the need to make them Wireable. This is an experimental feature and is subject to change. + +You can enable this feature by setting the config option in `data.php`: + +```php +'livewire' => [ + 'enable_synths' => false, +] +``` + +Once enabled, you can use data objects within your Livewire components without the need to make them Wireable: + +```php +class SongUpdateComponent extends Component +{ + public SongData $data; + + public function mount(public int $id): void + { + $this->data = SongData::from(Song::findOrFail($id)); + } + + public function save(): void + { + Artist::findOrFail($this->id)->update($this->data->toArray()); + } + + public function render(): string + { + return <<<'BLADE' +
+

Songs

+ + +

Title: {{ $data->title }}

+

Artist: {{ $data->artist }}

+ +
+ BLADE; + } +} +``` + +### Lazy + +It is possible to use Lazy properties, these properties will not be sent over the wire unless they're included. **Always +include properties permanently** because a data object is being transformed and then cast again between Livewire +requests the includes should be permanent. + +It is possible to query lazy nested data objects, it is however not possible to query lazy properties which are not a data: + +```php +use Spatie\LaravelData\Lazy; + +class LazySongData extends Data +{ + public function __construct( + public Lazy|ArtistData $artist, + public Lazy|string $title, + ) {} +} +``` + +Within your Livewire view + +```php +$this->data->artist->name; // Works +$this->data->title; // Does not work +``` + +### Validation + +Laravel data **does not provide validation** when using Livewire, you should do this yourself! This is because laravel-data +does not support object validation at the moment. Only validating payloads which eventually become data objects. +The validation could technically happen when hydrating the data object, but this is not implemented +because we cannot guarantee that every hydration happens when a user made sure the data is valid +and thus the payload should be validated. diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/validation-attributes.md b/_docs/laravel-libs/laravel-data/advanced-usage/validation-attributes.md new file mode 100644 index 0000000..673de2b --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/validation-attributes.md @@ -0,0 +1,1029 @@ +--- +title: Validation attributes +weight: 14 +--- + +These are all the validation attributes currently available in laravel-data. + +## Accepted + +[Docs](https://laravel.com/docs/validation#rule-accepted) + +```php +#[Accepted] +public bool $closure; +``` + +## AcceptedIf + +[Docs](https://laravel.com/docs/validation#rule-accepted-if) + +```php +#[AcceptedIf('other_field', 'equals_this')] +public bool $closure; +``` + +## ActiveUrl + +[Docs](https://laravel.com/docs/validation#rule-active-url) + +```php +#[ActiveUrl] +public string $closure; +``` + +## After + +[Docs](https://laravel.com/docs/validation#rule-after) + +```php +#[After('tomorrow')] +public Carbon $closure; + +#[After(Carbon::yesterday())] +public Carbon $closure; + +// Always use field references when referencing other fields +#[After(new FieldReference('other_field'))] +public Carbon $closure; +``` + +## AfterOrEqual + +[Docs](https://laravel.com/docs/validation#rule-after-or-equal) + +```php +#[AfterOrEqual('tomorrow')] +public Carbon $closure; + +#[AfterOrEqual(Carbon::yesterday())] +public Carbon $closure; + +// Always use field references when referencing other fields +#[AfterOrEqual(new FieldReference('other_field'))] +public Carbon $closure; +``` + +## Alpha + +[Docs](https://laravel.com/docs/validation#rule-alpha) + +```php +#[Alpha] +public string $closure; +``` + +## AlphaDash + +[Docs](https://laravel.com/docs/validation#rule-alpha-dash) + +```php +#[AlphaDash] +public string $closure; +``` + +## AlphaNumeric + +[Docs](https://laravel.com/docs/validation#rule-alpha-num) + +```php +#[AlphaNumeric] +public string $closure; +``` + +## ArrayType + +[Docs](https://laravel.com/docs/validation#rule-array) + +```php +#[ArrayType] +public array $closure; + +#[ArrayType(['valid_key', 'other_valid_key'])] +public array $closure; + +#[ArrayType('valid_key', 'other_valid_key')] +public array $closure; +``` + +## Bail + +[Docs](https://laravel.com/docs/validation#rule-bail) + +```php +#[Bail] +public string $closure; +``` + +## Before + +[Docs](https://laravel.com/docs/validation#rule-before) + +```php +#[Before('tomorrow')] +public Carbon $closure; + +#[Before(Carbon::yesterday())] +public Carbon $closure; + +// Always use field references when referencing other fields +#[Before(new FieldReference('other_field'))] +public Carbon $closure; +``` + +## BeforeOrEqual + +[Docs](https://laravel.com/docs/validation#rule-before-or-equal) + +```php +#[BeforeOrEqual('tomorrow')] +public Carbon $closure; + +#[BeforeOrEqual(Carbon::yesterday())] +public Carbon $closure; + +// Always use field references when referencing other fields +#[BeforeOrEqual(new FieldReference('other_field'))] +public Carbon $closure; +``` + +## Between + +[Docs](https://laravel.com/docs/validation#rule-between) + +```php +#[Between(3.14, 42)] +public int $closure; +``` + +## BooleanType + +[Docs](https://laravel.com/docs/validation#rule-boolean) + +```php +#[BooleanType] +public bool $closure; +``` + +## Confirmed + +[Docs](https://laravel.com/docs/validation#rule-confirmed) + +```php +#[Confirmed] +public string $closure; +``` + +## CurrentPassword + +[Docs](https://laravel.com/docs/validation#rule-current-password) + +```php +#[CurrentPassword] +public string $closure; + +#[CurrentPassword('api')] +public string $closure; +``` + +## Date + +[Docs](https://laravel.com/docs/validation#rule-date) + +```php +#[Date] +public Carbon $date; +``` + +## DateEquals + +[Docs](https://laravel.com/docs/validation#rule-date-equals) + +```php +#[DateEquals('tomorrow')] +public Carbon $date; + +#[DateEquals(Carbon::yesterday())] +public Carbon $date; +``` + +## DateFormat + +[Docs](https://laravel.com/docs/validation#rule-date-format) + +```php +#[DateFormat('d-m-Y')] +public Carbon $date; + +#[DateFormat(['Y-m-d', 'Y-m-d H:i:s'])] +public Carbon $date; +``` + +## Declined + +[Docs](https://laravel.com/docs/validation#rule-declined) + +```php +#[Declined] +public bool $closure; +``` + +## DeclinedIf + +[Docs](https://laravel.com/docs/validation#rule-declined-if) + +```php +#[DeclinedIf('other_field', 'equals_this')] +public bool $closure; +``` + +## Different + +[Docs](https://laravel.com/docs/validation#rule-different) + +```php +#[Different('other_field')] +public string $closure; +``` + +## Digits + +[Docs](https://laravel.com/docs/validation#rule-digits) + +```php +#[Digits(10)] +public int $closure; +``` + +## DigitsBetween + +[Docs](https://laravel.com/docs/validation#rule-digits-between) + +```php +#[DigitsBetween(2, 10)] +public int $closure; +``` + +## Dimensions + +[Docs](https://laravel.com/docs/validation#rule-dimensions) + +```php +#[Dimensions(ratio: 1.5)] +public UploadedFile $closure; + +#[Dimensions(maxWidth: 100, maxHeight: 100)] +public UploadedFile $closure; +``` + +## Distinct + +[Docs](https://laravel.com/docs/validation#rule-distinct) + +```php +#[Distinct] +public string $closure; + +#[Distinct(Distinct::Strict)] +public string $closure; + +#[Distinct(Distinct::IgnoreCase)] +public string $closure; +``` + +## DoesntEndWith + +[Docs](https://laravel.com/docs/validation#rule-doesnt-end-with) + +```php +#[DoesntEndWith('a')] +public string $closure; + +#[DoesntEndWith(['a', 'b'])] +public string $closure; + +#[DoesntEndWith('a', 'b')] +public string $closure; +``` + +## DoesntStartWith + +[Docs](https://laravel.com/docs/validation#rule-doesnt-start-with) + +```php +#[DoesntStartWith('a')] +public string $closure; + +#[DoesntStartWith(['a', 'b'])] +public string $closure; + +#[DoesntStartWith('a', 'b')] +public string $closure; +``` + +## Email + +[Docs](https://laravel.com/docs/validation#rule-email) + +```php +#[Email] +public string $closure; + +#[Email(Email::RfcValidation)] +public string $closure; + +#[Email([Email::RfcValidation, Email::DnsCheckValidation])] +public string $closure; + +#[Email(Email::RfcValidation, Email::DnsCheckValidation)] +public string $closure; +``` + +## EndsWith + +[Docs](https://laravel.com/docs/validation#rule-ends-with) + +```php +#[EndsWith('a')] +public string $closure; + +#[EndsWith(['a', 'b'])] +public string $closure; + +#[EndsWith('a', 'b')] +public string $closure; +``` + +## Enum + +[Docs](https://laravel.com/docs/validation#rule-enum) + +```php +#[Enum(ChannelType::class)] +public string $closure; + +#[Enum(ChannelType::class, only: [ChannelType::Email])] +public string $closure; + +#[Enum(ChannelType::class, except: [ChannelType::Email])] +public string $closure; +``` + +## ExcludeIf + +*At the moment the data is not yet excluded due to technical reasons, v4 should fix this* + +[Docs](https://laravel.com/docs/validation#rule-exclude-if) + +```php +#[ExcludeIf('other_field', 'has_value')] +public string $closure; +``` + +## ExcludeUnless + +*At the moment the data is not yet excluded due to technical reasons, v4 should fix this* + +[Docs](https://laravel.com/docs/validation#rule-exclude-unless) + +```php +#[ExcludeUnless('other_field', 'has_value')] +public string $closure; +``` + +## ExcludeWith + +*At the moment the data is not yet excluded due to technical reasons, v4 should fix this* + +[Docs](https://laravel.com/docs/validation#rule-exclude-with) + +```php +#[ExcludeWith('other_field')] +public string $closure; +``` + +## ExcludeWithout + +*At the moment the data is not yet excluded due to technical reasons, v4 should fix this* + +[Docs](https://laravel.com/docs/validation#rule-exclude-without) + +```php +#[ExcludeWithout('other_field')] +public string $closure; +``` + +## Exists + +[Docs](https://laravel.com/docs/validation#rule-exists) + +```php +#[Exists('users')] +public string $closure; + +#[Exists(User::class)] +public string $closure; + +#[Exists('users', 'email')] +public string $closure; + +#[Exists('users', 'email', connection: 'tenant')] +public string $closure; + +#[Exists('users', 'email', withoutTrashed: true)] +public string $closure; +``` + +## File + +[Docs](https://laravel.com/docs/validation#rule-file) + +```php +#[File] +public UploadedFile $closure; +``` + +## Filled + +[Docs](https://laravel.com/docs/validation#rule-filled) + +```php +#[Filled] +public string $closure; +``` + +## GreaterThan + +[Docs](https://laravel.com/docs/validation#rule-gt) + +```php +#[GreaterThan('other_field')] +public int $closure; +``` + +## GreaterThanOrEqualTo + +[Docs](https://laravel.com/docs/validation#rule-gte) + +```php +#[GreaterThanOrEqualTo('other_field')] +public int $closure; +``` + +## Image + +[Docs](https://laravel.com/docs/validation#rule-image) + +```php +#[Image] +public UploadedFile $closure; +``` + +## In + +[Docs](https://laravel.com/docs/validation#rule-in) + +```php +#[In([1, 2, 3, 'a', 'b'])] +public mixed $closure; + +#[In(1, 2, 3, 'a', 'b')] +public mixed $closure; +``` + +## InArray + +[Docs](https://laravel.com/docs/validation#rule-in-array) + +```php +#[InArray('other_field')] +public string $closure; +``` + +## IntegerType + +[Docs](https://laravel.com/docs/validation#rule-integer) + +```php +#[IntegerType] +public int $closure; +``` + +## IP + +[Docs](https://laravel.com/docs/validation#rule-ip) + +```php +#[IP] +public string $closure; +``` + +## IPv4 + +[Docs](https://laravel.com/docs/validation#ipv4) + +```php +#[IPv4] +public string $closure; +``` + +## IPv6 + +[Docs](https://laravel.com/docs/validation#ipv6) + +```php +#[IPv6] +public string $closure; +``` + +## Json + +[Docs](https://laravel.com/docs/validation#rule-json) + +```php +#[Json] +public string $closure; +``` + +## LessThan + +[Docs](https://laravel.com/docs/validation#rule-lt) + +```php +#[LessThan('other_field')] +public int $closure; +``` + +## LessThanOrEqualTo + +[Docs](https://laravel.com/docs/validation#rule-lte) + +```php +#[LessThanOrEqualTo('other_field')] +public int $closure; +``` + +## Lowercase + +[Docs](https://laravel.com/docs/validation#rule-lowercase) + +```php +#[Lowercase] +public string $closure; +``` + +## ListType + +[Docs](https://laravel.com/docs/validation#rule-list) + +```php +#[ListType] +public array $array; +``` + +## MacAddress + +[Docs](https://laravel.com/docs/validation#rule-mac) + +```php +#[MacAddress] +public string $closure; +``` + +## Max + +[Docs](https://laravel.com/docs/validation#rule-max) + +```php +#[Max(20)] +public int $closure; +``` + +## MaxDigits + +[Docs](https://laravel.com/docs/validation#rule-max-digits) + +```php +#[MaxDigits(10)] +public int $closure; +``` + +## MimeTypes + +[Docs](https://laravel.com/docs/validation#rule-mimetypes) + +```php +#[MimeTypes('video/quicktime')] +public UploadedFile $closure; + +#[MimeTypes(['video/quicktime', 'video/avi'])] +public UploadedFile $closure; + +#[MimeTypes('video/quicktime', 'video/avi')] +public UploadedFile $closure; +``` + +## Mimes + +[Docs](https://laravel.com/docs/validation#rule-mimes) + +```php +#[Mimes('jpg')] +public UploadedFile $closure; + +#[Mimes(['jpg', 'png'])] +public UploadedFile $closure; + +#[Mimes('jpg', 'png')] +public UploadedFile $closure; +``` + +## Min + +[Docs](https://laravel.com/docs/validation#rule-min) + +```php +#[Min(20)] +public int $closure; +``` + +## MinDigits + +[Docs](https://laravel.com/docs/validation#rule-min-digits) + +```php +#[MinDigits(2)] +public int $closure; +``` + +## MultipleOf + +[Docs](https://laravel.com/docs/validation#rule-multiple-of) + +```php +#[MultipleOf(3)] +public int $closure; +``` + +## NotIn + +[Docs](https://laravel.com/docs/validation#rule-not-in) + +```php +#[NotIn([1, 2, 3, 'a', 'b'])] +public mixed $closure; + +#[NotIn(1, 2, 3, 'a', 'b')] +public mixed $closure; +``` + +## NotRegex + +[Docs](https://laravel.com/docs/validation#rule-not-regex) + +```php +#[NotRegex('/^.+$/i')] +public string $closure; +``` + +## Nullable + +[Docs](https://laravel.com/docs/validation#rule-nullable) + +```php +#[Nullable] +public ?string $closure; +``` + +## Numeric + +[Docs](https://laravel.com/docs/validation#rule-numeric) + +```php +#[Numeric] +public ?string $closure; +``` + +## Password + +[Docs](https://laravel.com/docs/validation#rule-password) + +```php +#[Password(min: 12, letters: true, mixedCase: true, numbers: false, symbols: false, uncompromised: true, uncompromisedThreshold: 0)] +public string $closure; +``` + +## Present + +[Docs](https://laravel.com/docs/validation#rule-present) + +```php +#[Present] +public string $closure; +``` + +## Prohibited + +[Docs](https://laravel.com/docs/validation#rule-prohibited) + +```php +#[Prohibited] +public ?string $closure; +``` + +## ProhibitedIf + +[Docs](https://laravel.com/docs/validation#rule-prohibited-if) + +```php +#[ProhibitedIf('other_field', 'has_value')] +public ?string $closure; + +#[ProhibitedIf('other_field', ['has_value', 'or_this_value'])] +public ?string $closure; +``` + +## ProhibitedUnless + +[Docs](https://laravel.com/docs/validation#rule-prohibited-unless) + +```php +#[ProhibitedUnless('other_field', 'has_value')] +public ?string $closure; + +#[ProhibitedUnless('other_field', ['has_value', 'or_this_value'])] +public ?string $closure; +``` + +## Prohibits + +[Docs](https://laravel.com/docs/validation#rule-prohibits) + +```php +#[Prohibits('other_field')] +public ?string $closure; + +#[Prohibits(['other_field', 'another_field'])] +public ?string $closure; + +#[Prohibits('other_field', 'another_field')] +public ?string $closure; +``` + +## Regex + +[Docs](https://laravel.com/docs/validation#rule-regex) + +```php +#[Regex('/^.+$/i')] +public string $closure; +``` + +## Required + +[Docs](https://laravel.com/docs/validation#rule-required) + +```php +#[Required] +public string $closure; +``` + +## RequiredIf + +[Docs](https://laravel.com/docs/validation#rule-required-if) + +```php +#[RequiredIf('other_field', 'value')] +public ?string $closure; + +#[RequiredIf('other_field', ['value', 'another_value'])] +public ?string $closure; +``` + +## RequiredUnless + +[Docs](https://laravel.com/docs/validation#rule-required-unless) + +```php +#[RequiredUnless('other_field', 'value')] +public ?string $closure; + +#[RequiredUnless('other_field', ['value', 'another_value'])] +public ?string $closure; +``` + +## RequiredWith + +[Docs](https://laravel.com/docs/validation#rule-required-with) + +```php +#[RequiredWith('other_field')] +public ?string $closure; + +#[RequiredWith(['other_field', 'another_field'])] +public ?string $closure; + +#[RequiredWith('other_field', 'another_field')] +public ?string $closure; +``` + +## RequiredWithAll + +[Docs](https://laravel.com/docs/validation#rule-required-with-all) + +```php +#[RequiredWithAll('other_field')] +public ?string $closure; + +#[RequiredWithAll(['other_field', 'another_field'])] +public ?string $closure; + +#[RequiredWithAll('other_field', 'another_field')] +public ?string $closure; +``` + +## RequiredWithout + +[Docs](https://laravel.com/docs/validation#rule-required-without) + +```php +#[RequiredWithout('other_field')] +public ?string $closure; + +#[RequiredWithout(['other_field', 'another_field'])] +public ?string $closure; + +#[RequiredWithout('other_field', 'another_field')] +public ?string $closure; +``` + +## RequiredWithoutAll + +[Docs](https://laravel.com/docs/validation#rule-required-without-all) + +```php +#[RequiredWithoutAll('other_field')] +public ?string $closure; + +#[RequiredWithoutAll(['other_field', 'another_field'])] +public ?string $closure; + +#[RequiredWithoutAll('other_field', 'another_field')] +public ?string $closure; +``` + +## RequiredArrayKeys + +[Docs](https://laravel.com/docs/validation#rule-required-array-keys) + +```php +#[RequiredArrayKeys('a')] +public array $closure; + +#[RequiredArrayKeys(['a', 'b'])] +public array $closure; + +#[RequiredArrayKeys('a', 'b')] +public array $closure; +``` + +## Rule + +```php +#[Rule('string|uuid')] +public string $closure; + +#[Rule(['string','uuid'])] +public string $closure; +``` + +## Same + +[Docs](https://laravel.com/docs/validation#rule-same) + +```php +#[Same('other_field')] +public string $closure; +``` + +## Size + +[Docs](https://laravel.com/docs/validation#rule-size) + +```php +#[Size(10)] +public string $closure; +``` + +## Sometimes + +[Docs](https://laravel.com/docs/validation#validating-when-present) + +```php +#[Sometimes] +public string $closure; +``` + +## StartsWith + +[Docs](https://laravel.com/docs/validation#rule-starts-with) + +```php +#[StartsWith('a')] +public string $closure; + +#[StartsWith(['a', 'b'])] +public string $closure; + +#[StartsWith('a', 'b')] +public string $closure; +``` + +## StringType + +[Docs](https://laravel.com/docs/validation#rule-string) + +```php +#[StringType()] +public string $closure; +``` + +## TimeZone + +[Docs](https://laravel.com/docs/validation#rule-timezone) + +```php +#[TimeZone()] +public string $closure; +``` + +## Unique + +[Docs](https://laravel.com/docs/validation#rule-unique) + +```php +#[Unique('users')] +public string $closure; + +#[Unique(User::class)] +public string $closure; + +#[Unique('users', 'email')] +public string $closure; + +#[Unique('users', connection: 'tenant')] +public string $closure; + +#[Unique('users', withoutTrashed: true)] +public string $closure; + +#[Unique('users', ignore: 5)] +public string $closure; + +#[Unique('users', ignore: new AuthenticatedUserReference())] +public string $closure; + +#[Unique('posts', ignore: new RouteParameterReference('post'))] +public string $closure; +``` + +## Uppercase + +[Docs](https://laravel.com/docs/validation#rule-uppercase) + +```php +#[Uppercase] +public string $closure; +``` + +## Url + +[Docs](https://laravel.com/docs/validation#rule-url) + +```php +#[Url] +public string $closure; +``` + +```php +#[Url(['http', 'https'])] +public string $closure; +``` + +## Ulid + +[Docs](https://laravel.com/docs/validation#rule-ulid) + +```php +#[Ulid] +public string $closure; +``` + +## Uuid + +[Docs](https://laravel.com/docs/validation#rule-uuid) + +```php +#[Uuid] +public string $closure; +``` diff --git a/_docs/laravel-libs/laravel-data/advanced-usage/working-with-dates.md b/_docs/laravel-libs/laravel-data/advanced-usage/working-with-dates.md new file mode 100644 index 0000000..1cd5760 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/advanced-usage/working-with-dates.md @@ -0,0 +1,86 @@ +--- +title: Working with dates +weight: 3 +--- + +Dates can be hard, there are tons of formats to cast them from or transform them to. Within the `data.php` config file a +default date format can be set: + +```php + 'date_format' => DATE_ATOM, +``` + +Now when using the `DateTimeInterfaceCast` or `DateTimeInterfaceTransformer` the format defined will be used + +```php +#[WithCast(DateTimeInterfaceCast::class)] +#[WithTransformer(DateTimeInterfaceTransformer::class)] +public DateTime $date +``` + +It is also possible to manually set the format; + +```php +#[WithCast(DateTimeInterfaceCast::class, format: DATE_ATOM)] +#[WithTransformer(DateTimeInterfaceTransformer::class, format: DATE_ATOM)] +public DateTime $date +``` + +When casting the data object will use the type of the property to cast a date string into, so if you want to +use `Carbon`, that's perfectly possible: + +```php +#[WithCast(DateTimeInterfaceCast::class)] +public Carbon $date +``` + +You can even manually specify the type the date string should be cast to: + +```php + +#[WithCast(DateTimeInterfaceCast::class, type: CarbonImmutable::class)] +public $date +``` + +## Multiple date formats + +Sometimes your application might use different date formats, for example, you receive dates from an IOS and React +application. These use different underlying date formats. In such case you can add an array to the `date_format` key +within the `data.php` config file: + +```php + 'date_format' => [DATE_ATOM, 'Y-m-d'], +``` + +Now when casting a date, a valid format will be searched. When none can be found, an exception is thrown. + +When a transformers hasn't explicitly stated its format, the first format within the array is used. + +## Casting dates in a different time zone + +Sometimes a date can be in a different timezone than the timezone you application uses. For example, if your application uses `Europe/Brussels` but your date is in `UTC`: + +```php +#[WithCast(DateTimeInterfaceCast::class, timeZone: 'UTC')] +public DateTime $date +``` + +The date will be created with the `UTC` timezone but will be the same as in the `Europe/Brussels` timezone. + +## Changing time zones + +When casting a date you may want to set an alternative timezone this can be achieved as such: + +```php +#[WithCast(DateTimeInterfaceCast::class, setTimeZone: 'Europe/Brussels')] +public DateTime $date +``` + +In this case the time will be transformed, if our original time was in `UTC` then one or two hours (depending on summer time) will be added. + +You can also change the timezone of a property which is getting transformed: + +```php +#[WithTransformer(DateTimeInterfaceTransformer::class, setTimeZone: 'Europe/Brussels')] +public DateTime $date +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/_index.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/_index.md new file mode 100644 index 0000000..d5babe3 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/_index.md @@ -0,0 +1,4 @@ +--- +title: As a DTO +weight: 2 +--- diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/abstract-data.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/abstract-data.md new file mode 100644 index 0000000..db04d53 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/abstract-data.md @@ -0,0 +1,98 @@ +--- +title: Abstract Data +weight: 4 +--- + +It is possible to create an abstract data class with subclasses extending it: + +```php +abstract class Person extends Data +{ + public string $name; +} + +class Singer extends Person +{ + public function __construct( + public string $voice, + ) {} +} + +class Musician extends Person +{ + public function __construct( + public string $instrument, + ) {} +} +``` + +It is perfectly possible now to create individual instances as follows: + +```php +Singer::from(['name' => 'Rick Astley', 'voice' => 'tenor']); +Musician::from(['name' => 'Rick Astley', 'instrument' => 'guitar']); +``` + +But what if you want to use this abstract type in another data class like this: + +```php +class Contract extends Data +{ + public string $label; + public Person $artist; +} +``` + +While the following may both be valid: + +```php +Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'voice' => 'tenor']]); +Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'instrument' => 'guitar']]); +``` + +The package can't decide which subclass to construct for the property. + +You can implement the `PropertyMorphableData` interface on the abstract class to solve this. This interface adds a `morph` method that will be used to determine which subclass to use. The `morph` method receives an array of properties limited to properties tagged by a `PropertyForMorph` attribute. + +```php +use Spatie\LaravelData\Attributes\PropertyForMorph; +use Spatie\LaravelData\Contracts\PropertyMorphableData; + +abstract class Person extends Data implements PropertyMorphableData +{ + #[PropertyForMorph] + public string $type; + + public string $name; + + public static function morph(array $properties): ?string + { + return match ($properties['type']) { + 'singer' => Singer::class, + 'musician' => Musician::class, + default => null + }; + } +} +``` + +The example above will work by adding this code, and the correct Data class will be constructed. + +Since the morph functionality needs to run early within the data construction process, it bypasses the normal flow of constructing data objects so there are a few limitations: + +- it is only allowed to use properties typed as string, int, or BackedEnum(int or string) +- When a property is typed as an enum, the value passed to the morph method will be an enum +- it can be that the value of a property within the morph method is null or a different type than expected since it runs before validation +- properties with mapped property names are still supported + +It is also possible to use abstract data classes as collections as such: + +```php +class Band extends Data +{ + public string $name; + + /** @var array */ + public array $members; +} +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/casts.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/casts.md new file mode 100644 index 0000000..cfadf33 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/casts.md @@ -0,0 +1,164 @@ +--- +title: Casts +weight: 5 +--- + +We extend our example data object just a little bit: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + public DateTime $date, + public Format $format, + ) { + } +} +``` + +The `Format` property here is an `Enum` and looks like this: + +```php +enum Format: string { + case cd = 'cd'; + case vinyl = 'vinyl'; + case cassette = 'cassette'; +} +``` + +When we now try to construct a data object like this: + +```php +SongData::from([ + 'title' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'date' => '27-07-1987', + 'format' => 'vinyl', +]); +``` + +And get an error because the first two properties are simple PHP types(strings, ints, floats, booleans, arrays), but the following two properties are more complex types: `DateTime` and `Enum`, respectively. + +These types cannot be automatically created. A cast is needed to construct them from a string. + +There are two types of casts, local and global casts. + +## Local casts + +Local casts are defined within the data object itself and can be added using attributes: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + #[WithCast(DateTimeInterfaceCast::class)] + public DateTime $date, + #[WithCast(EnumCast::class)] + public Format $format, + ) { + } +} +``` + +Now it is possible to create a data object like this without exceptions: + +```php +SongData::from([ + 'title' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'date' => '27-07-1987', + 'format' => 'vinyl', +]); +``` + +It is possible to provide parameters to the casts like this: + +```php +#[WithCast(EnumCast::class, type: Format::class)] +public Format $format +``` + +## Global casts + +Global casts are not defined on the data object but in your `data.php` config file: + +```php +'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, +], +``` + +When the data object can find no local cast for the property, the package will look through the global casts and tries to find a suitable cast. You can define casts for: + +- a **specific implementation** (e.g. CarbonImmutable) +- an **interface** (e.g. DateTimeInterface) +- a **base class** (e.g. Enum) + +As you can see, the package by default already provides a `DateTimeInterface` cast, this means we can update our data object like this: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + public DateTime $date, + #[WithCast(EnumCast::class)] + public Format $format, + ) { + } +} +``` + +Tip: we can also remove the `EnumCast` since the package will automatically cast enums because they're a native PHP type, but this made the example easy to understand. + +## Creating your own casts + +It is possible to create your casts. You can read more about this in the [advanced chapter](/docs/laravel-data/v4/advanced-usage/creating-a-cast). + +## Casting arrays or collections of non-data types + +We've already seen how collections of data can be made of data objects, the same is true for all other types if correctly +typed. + +Let say we have an array of DateTime objects: + +```php +class ReleaseData extends Data +{ + public string $title; + /** @var array */ + public array $releaseDates; +} +``` + +By enabling the `cast_and_transform_iterables` feature in the `data` config file (this feature will be enabled by default in laravel-data v5): + +```php +'features' => [ + 'cast_and_transform_iterables' => true, +], +``` + +We now can create a `ReleaseData` object with an array of strings which will be cast into an array DateTime objects: + +```php +ReleaseData::from([ + 'title' => 'Never Gonna Give You Up', + 'releaseDates' => [ + '1987-07-27T12:00:00Z', + '1987-07-28T12:00:00Z', + '1987-07-29T12:00:00Z', + ], +]); +``` + +For this feature to work, a cast should not only implement the `Cast` interface but also the `IterableItemCast`. The +signatures of the `cast` and `castIterableItem` methods are exactly the same, but they're called on different times. +When casting a property like a DateTime from a string, the `cast` method will be used, when transforming an iterable +property like an array or Laravel Collection where the iterable item is typed using an annotation, then each item of the +provided iterable will trigger a call to the `castIterableItem` method. diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/collections.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/collections.md new file mode 100644 index 0000000..f44f9ed --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/collections.md @@ -0,0 +1,266 @@ +--- +title: Collections +weight: 3 +--- + +It is possible to create a collection of data objects by using the `collect` method: + +```php +SongData::collect([ + ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'], +]); // returns an array of SongData objects +``` + +Whatever type of collection you pass in, the package will return the same type of collection with the freshly created +data objects within it. As long as this type is an array, Laravel collection or paginator or a class extending from it. + +This opens up possibilities to create collections of Eloquent models: + +```php +SongData::collect(Song::all()); // return an Eloquent collection of SongData objects +``` + +Or use a paginator: + +```php +SongData::collect(Song::paginate()); // return a LengthAwarePaginator of SongData objects + +// or + +SongData::collect(Song::cursorPaginate()); // return a CursorPaginator of SongData objects +``` + +Internally the `from` method of the data class will be used to create a new data object for each item in the collection. + +When the collection already contains data objects, the `collect` method will return the same collection: + +```php +SongData::collect([ + SongData::from(['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley']), + SongData::from(['title' => 'Giving Up on Love', 'artist' => 'Rick Astley']), +]); // returns an array of SongData objects +``` + +The collect method also allows you to cast collections from one type into another. For example, you can pass in +an `array`and get back a Laravel collection: + +```php +SongData::collect($songs, Collection::class); // returns a Laravel collection of SongData objects +``` + +This transformation will only work with non-paginator collections. + +## Magically creating collections + +We've already seen that `from` can create data objects magically. It is also possible to create a collection of data +objects magically when using `collect`. + +Let's say you've implemented a custom collection class called `SongCollection`: + +```php +class SongCollection extends Collection +{ + public function __construct( + $items = [], + public array $artists = [], + ) { + parent::__construct($items); + } +} +``` + +Since the constructor of this collection requires an extra property it cannot be created automatically. However, it is +possible to define a custom collect method which can create it: + +```php +class SongData extends Data +{ + public string $title; + public string $artist; + + public static function collectArray(array $items): SongCollection + { + return new SongCollection( + parent::collect($items), + array_unique(array_map(fn(SongData $song) => $song->artist, $items)) + ); + } +} +``` + +Now when collecting an array data objects a `SongCollection` will be returned: + +```php +SongData::collectArray([ + ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Living on a prayer', 'artist' => 'Bon Jovi'], +]); // returns an SongCollection of SongData objects +``` + +There are a few requirements for this to work: + +- The method must be **static** +- The method must be **public** +- The method must have a **return type** +- The method name must **start with collect** +- The method name must not be **collect** + +## Creating a data object with collections + +You can create a data object with a collection of data objects just like you would create a data object with a nested +data object: + +```php +use App\Data\SongData; +use Illuminate\Support\Collection; + +class AlbumData extends Data +{ + public string $title; + /** @var Collection */ + public Collection $songs; +} + +AlbumData::from([ + 'title' => 'Never Gonna Give You Up', + 'songs' => [ + ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'], + ] +]); +``` + +Since the collection type here is a `Collection`, the package will automatically convert the array into a collection of +data objects. + +## DataCollections, PaginatedDataCollections and CursorPaginatedCollections + +The package also provides a few collection classes which can be used to create collections of data objects. It was a +requirement to use these classes in the past versions of the package when nesting data objects collections in data +objects. This is no longer the case, but there are still valid use cases for them. + +You can create a DataCollection like this: + +```php +use Spatie\LaravelData\DataCollection; + +SongData::collect(Song::all(), DataCollection::class); +``` + +A PaginatedDataCollection can be created like this: + +```php +use Spatie\LaravelData\PaginatedDataCollection; + +SongData::collect(Song::paginate(), PaginatedDataCollection::class); +```` + +And a CursorPaginatedCollection can be created like this: + +```php +use Spatie\LaravelData\CursorPaginatedCollection; + +SongData::collect(Song::cursorPaginate(), CursorPaginatedCollection::class); +``` + +### Why using these collection classes? + +We advise you to always use arrays, Laravel collections and paginators within your data objects. But let's say you have +a controller like this: + +```php +class SongController +{ + public function index() + { + return SongData::collect(Song::all()); + } +} +``` + +In the next chapters of this documentation, we'll see that it is possible to include or exclude properties from the data +objects like this: + +```php +class SongController +{ + public function index() + { + return SongData::collect(Song::all(), DataCollection::class)->include('artist'); + } +} +``` + +This will only work when you're using a `DataCollection`, `PaginatedDataCollection` or `CursorPaginatedCollection`. + +### DataCollections + +DataCollections provide some extra functionalities like: + +```php +// Counting the amount of items in the collection +count($collection); + +// Changing an item in the collection +$collection[0]->title = 'Giving Up on Love'; + +// Adding an item to the collection +$collection[] = SongData::from(['title' => 'Never Knew Love', 'artist' => 'Rick Astley']); + +// Removing an item from the collection +unset($collection[0]); +``` + +It is even possible to loop over it with a foreach: + +```php +foreach ($songs as $song){ + echo $song->title; +} +``` + +The `DataCollection` class implements a few of the Laravel collection methods: + +- through +- map +- filter +- first +- each +- values +- where +- reduce +- sole + +You can, for example, get the first item within a collection like this: + +```php +SongData::collect(Song::all(), DataCollection::class)->first(); // SongData object +``` + +### The `collection` method + +In previous versions of the package it was possible to use the `collection` method to create a collection of data +objects: + +```php +SongData::collection(Song::all()); // returns a DataCollection of SongData objects +SongData::collection(Song::paginate()); // returns a PaginatedDataCollection of SongData objects +SongData::collection(Song::cursorPaginate()); // returns a CursorPaginatedCollection of SongData objects +``` + +This method was removed with version v4 of the package in favor for the more powerful `collect` method. The `collection` +method can still be used by using the `WithDeprecatedCollectionMethod` trait: + +```php +use Spatie\LaravelData\Concerns\WithDeprecatedCollectionMethod; + +class SongData extends Data +{ + use WithDeprecatedCollectionMethod; + + // ... +} +``` + +Please note that this trait will be removed in the next major version of the package. diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/computed.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/computed.md new file mode 100644 index 0000000..12812bd --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/computed.md @@ -0,0 +1,38 @@ +--- +title: Computed values +weight: 9 +--- + +Earlier we saw how default values can be set for a data object, sometimes you want to set a default value based on other properties. For example, you might want to set a `full_name` property based on a `first_name` and `last_name` property. You can do this by using a computed property: + +```php +use Spatie\LaravelData\Attributes\Computed; + +class SongData extends Data +{ + #[Computed] + public string $full_name; + + public function __construct( + public string $first_name, + public string $last_name, + ) { + $this->full_name = "{$this->first_name} {$this->last_name}"; + } +} +``` + +You can now do the following: + +```php +SongData::from(['first_name' => 'Ruben', 'last_name' => 'Van Assche']); +``` + +Please notice: the computed property won't be reevaluated when its dependencies change. If you want to update a computed property, you'll have to create a new object. + +Again there are a few conditions for this approach: + +- You must always use a sole property, a property within the constructor definition won't work +- Computed properties cannot be defined in the payload, a `CannotSetComputedValue` will be thrown if this is the case +- If the `ignore_exception_when_trying_to_set_computed_property_value` configuration option is set to `true`, the computed property will be silently ignored when trying to set it in the payload and no `CannotSetComputedValue` exception will be thrown. + diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/creating-a-data-object.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/creating-a-data-object.md new file mode 100644 index 0000000..ca60c60 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/creating-a-data-object.md @@ -0,0 +1,213 @@ +--- +title: Creating a data object +weight: 1 +--- + +Let's get started with the following simple data object: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +Since this is just a simple PHP object, it can be initialized as such: + +```php +new SongData('Never gonna give you up', 'Rick Astley'); +``` + +But with this package, you can initialize the data object also with an array: + +```php +SongData::from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +You can use the `from` method to create a data object from nearly anything. For example, let's say you have an Eloquent +model like this: + +```php +class Song extends Model +{ + // Your model code +} +``` + +You can create a data object from such a model like this: + +```php +SongData::from(Song::firstOrFail($id)); +``` + +The package will find the required properties within the model and use them to construct the data object. + +Data can also be created from JSON strings: + +```php +SongData::from('{"title" : "Never Gonna Give You Up","artist" : "Rick Astley"}'); +``` + +Although the PHP 8.0 constructor properties look great in data objects, it is perfectly valid to use regular properties +without a constructor like so: + +```php +class SongData extends Data +{ + public string $title; + public string $artist; +} +``` + +## Magical creation + +It is possible to overwrite or extend the behaviour of the `from` method for specific types. So you can construct a data +object in a specific manner for that type. This can be done by adding a static method starting with 'from' to the data +object. + +For example, we want to change how we create a data object from a model. We can add a `fromModel` static method that +takes the model we want to use as a parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromModel(Song $song): self + { + return new self("{$song->title} ({$song->year})", $song->artist); + } +} +``` + +Now when creating a data object from a model like this: + +```php +SongData::from(Song::firstOrFail($id)); +``` + +Instead of the default method, the `fromModel` method will be called to create a data object from the found model. + +You're truly free to add as many from methods as you want. For example, you could add one to create a data object from a +string: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromString(string $string): self + { + [$title, $artist] = explode('|', $string); + + return new self($title, $artist); + } +} +``` + +From now on, you can create a data object like this: + +```php +SongData::from('Never gonna give you up|Rick Astley'); +``` + +It is also possible to use multiple arguments in a magical creation method: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromMultiple(string $title, string $artist): self + { + return new self($title, $artist); + } +} +``` + +Now we can create the data object like this: + +```php +SongData::from('Never gonna give you up', 'Rick Astley'); +``` + +There are a few requirements to enable magical data object creation: + +- The method must be **static and public** +- The method must **start with from** +- The method cannot be called **from** + +When the package cannot find such a method for a type given to the data object's `from` method. Then the data object +will try to create itself from the following types: + +- An *Eloquent model* by calling `toArray` on it +- A *Laravel request* by calling `all` on it +- An *Arrayable* by calling `toArray` on it +- An *array* + +This list can be extended using extra normalizers, find more about +it [here](/docs/laravel-data/v4/advanced-usage/normalizers). + +When a data object cannot be created using magical methods or the default methods, a `CannotCreateData` +exception will be thrown. + +## Optional creation + +It is impossible to return `null` from a data object's `from` method since we always expect a data object when +calling `from`. To solve this, you can call the `optional` method: + +```php +SongData::optional(null); // returns null +``` + +Underneath the optional method will call the `from` method when a value is given, so you can still magically create data +objects. When a null value is given, it will return null. + +## Creation without magic methods + +You can ignore the magical creation methods when creating a data object as such: + +```php +SongData::factory()->withoutMagicalCreation()->from($song); +``` + +## Advanced creation using factories + +It is possible to configure how a data object is created, whether it will be validated, which casts to use and more. You +can read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/factories). + +## DTO classes + +The default `Data` class from which you extend your data objects is a multi versatile class, it packs a lot of +functionality. But sometimes you just want a simple DTO class. You can use the `Dto` class for this: + +```php +class SongData extends Dto +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +The `Dto` class is a data class in its most basic form. It can be created from anything using magical methods, can +validate payloads before creating the data object and can be created using factories. But it doesn't have any of the +other functionality that the `Data` class has. diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/defaults.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/defaults.md new file mode 100644 index 0000000..d217f09 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/defaults.md @@ -0,0 +1,54 @@ +--- +title: Default values +weight: 8 +--- + +There are a few ways to define default values for a data object. Since a data object is just a regular PHP class, you can use the constructor to set default values: + +```php +class SongData extends Data +{ + public function __construct( + public string $title = 'Never Gonna Give You Up', + public string $artist = 'Rick Astley', + ) { + } +} +``` + +This works for simple types like strings, integers, floats, booleans, enums and arrays. But what if you want to set a default value for a more complex type like a `CarbonImmutable` object? You can use the constructor to do this: + +```php +class SongData extends Data +{ + #[Date] + public CarbonImmutable|Optional $date; + + public function __construct( + public string $title = 'Never Gonna Give You Up', + public string $artist = 'Rick Astley', + ) { + $this->date = CarbonImmutable::create(1987, 7, 27); + } +} +``` + +You can now do the following: + +```php +SongData::from(); +SongData::from(['title' => 'Giving Up On Love', 'date' => CarbonImmutable::create(1988, 4, 15)]); +``` + +Even validation will work: + +```php +SongData::validateAndCreate(); +SongData::validateAndCreate(['title' => 'Giving Up On Love', 'date' => CarbonImmutable::create(1988, 4, 15)]); +``` + +There are a few conditions for this approach: + +- You must always use a sole property, a property within the constructor definition won't work +- The optional type is technically not required, but it's a good idea to use it otherwise the validation won't work +- Validation won't be performed on the default value, so make sure it is valid diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/factories.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/factories.md new file mode 100644 index 0000000..651db34 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/factories.md @@ -0,0 +1,139 @@ +--- +title: Factories +weight: 13 +--- + +It is possible to automatically create data objects in all sorts of forms with this package. Sometimes a little bit more +control is required when a data object is being created. This is where factories come in. + +Factories allow you to create data objects like before but allow you to customize the creation process. + +For example, we can create a data object using a factory like this: + +```php +SongData::factory()->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +Collecting a bunch of data objects using a factory can be done as such: + +```php +SongData::factory()->collect(Song::all()) +``` + +## Disable property name mapping + +We saw [earlier](/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names) that it is possible to map +property names when creating a data object from an array. This can be disabled when using a factory: + +```php +ContractData::factory()->withoutPropertyNameMapping()->from(['name' => 'Rick Astley', 'record_company' => 'RCA Records']); // record_company will not be mapped to recordCompany +``` + +## Changing the validation strategy + +By default, the package will only validate Requests when creating a data object it is possible to change the validation +strategy to always validate for each type: + +```php +SongData::factory()->alwaysValidate()->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +Or completely disable validation: + +```php +SongData::factory()->withoutValidation()->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +## Disabling magic methods + +A data object can be created +using [magic methods](/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object.md#magical-creation) , this can be disabled +when using a factory: + +```php +SongData::factory()->withoutMagicalCreation()->from('Never gonna give you up'); // Won't work since the magical method creation is disabled +``` + +It is also possible to ignore the magical creation methods when creating a data object as such: + +```php +SongData::factory()->ignoreMagicalMethod('fromString')->from('Never gonna give you up'); // Won't work since the magical method is ignored +``` + +## Disabling optional values + +When creating a data object that has optional properties, it is possible choose whether missing properties from the payload should be created as `Optional`. This can be helpful when you want to have a `null` value instead of an `Optional` object - for example, when creating the DTO from an Eloquent model with `null` values. + +```php +class SongData extends Data { + public function __construct( + public string $title, + public string $artist, + public Optional|null|string $album, + ) { + } +} + +SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); // album will `null` instead of `Optional` +``` + +Note that when an Optional property has no default value, and is not nullable, and the payload does not contain a value for this property, the DTO will not have the property set - so accessing it can throw `Typed property must not be accessed before initialization` error. Therefore, it's advisable to either set a default value or make the property nullable, when using `withoutOptionalValues`. + +```php +class SongData extends Data { + public function __construct( + public string $title, + public string $artist, + public Optional|string $album, // careful here! + public Optional|string $publisher = 'unknown', + public Optional|string|null $label, + ) { + } +} + +$data = SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); + +$data->toArray(); // ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley', 'publisher' => 'unknown', 'label' => null] + +$data->album; // accessing the album will throw an error, unless the property is set before accessing it +``` + +## Adding additional global casts + +When creating a data object, it is possible to add additional casts to the data object: + +```php +SongData::factory()->withCast('string', StringToUpperCast::class)->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +These casts will not replace the other global casts defined in the `data.php` config file, they will though run before +the other global casts. You define them just like you would define them in the config file, the first parameter is the +type of the property that should be cast and the second parameter is the cast class. + +## Using the creation context + +Internally the package uses a creation context to create data objects. The factory allows you to use this context manually, but when using the from method it will be used automatically. + +It is possible to inject the creation context into a magical method by adding it as a parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromModel(Song $song, CreationContext $context): self + { + // Do something with the context + } +} +``` + +You can read more about creation contexts [here](/docs/laravel-data/v4/advanced-usage/pipeline). diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/injecting-property-values.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/injecting-property-values.md new file mode 100644 index 0000000..4e97f78 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/injecting-property-values.md @@ -0,0 +1,232 @@ +--- +title: Injecting property values +weight: 12 +--- + +When creating a data object, it is possible to inject values into properties from all kinds of sources like route +parameters, the current user or dependencies in the container. + +## Filling properties from a route parameter + +When creating data objects from requests, it's possible to automatically fill data properties from request route +parameters, such as route models. + +The `FromRouteParameter` attribute allows filling properties with route parameter values. + +### Using scalar route parameters + +```php +Route::patch('/songs/{songId}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameter('songId')] + public int $id; + public string $name; +} +``` + +Here, the `$id` property will be filled with the `songId` route parameter value (which most likely is a string or +integer). + +### Using Models, objects or arrays as route parameters + +Given that we have a route to create songs for a specific author, and that the `{author}` route parameter uses route +model binding to automatically bind to an `Author` model: + +```php +Route::post('/songs/{artist}', [SongController::class, 'store']); + +class SongData extends Data { + public int $id; + #[FromRouteParameter('artist')] + public ArtistData $author; +} +``` + +Here, the `$artist` property will be filled with the `artist` route parameter value, which will be an instance of the +`Artist` model. Note that the package will automatically cast the model to `ArtistData`. + +## Filling properties from route parameter properties + +The `FromRouteParameterProperty` attribute allows filling properties with values from route parameter properties. The +main difference from `FromRouteParameter` is that the former uses the full route parameter value, while +`FromRouteParameterProperty` uses a single property from the route parameter. + +In the example below, we're using route model binding. `{song}` represents an instance of the `Song` model. +`FromRouteParameterProperty` automatically attempts to fill the `SongData` `$id` property from `$song->id`. + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + public string $name; +} +``` + +### Using custom property mapping + +In the example below, `$name` property will be filled with `$song->title` (instead of `$song->name). + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + #[FromRouteParameterProperty('song', 'title')] + public string $name; +} +``` + +### Nested property mapping + +Nested properties are supported as well. Here, we fill `$singerName` from `$artist->leadSinger->name`: + +```php +Route::patch('/artists/{artist}/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + #[FromRouteParameterProperty('artist', 'leadSinger.name')] + public string $singerName; +} +``` + +## Route parameters take priority over request body + +By default, route parameters take priority over values in the request body. For example, when the song ID is present in +the route model as well as request body, the ID from route model is used. + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +// PATCH /songs/123 +// { "id": 321, "name": "Never gonna give you up" } + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + public string $name; +} +``` + +Here, `$id` will be `123` even though the request body has `321` as the ID value. + +In most cases, this is useful - especially when you need the ID for a validation rule. However, there may be cases when +the exact opposite is required. + +The above behavior can be turned off by switching the `replaceWhenPresentInPayload` flag off. This can be useful when +you _intend_ to allow updating a property that is present in a route parameter, such as a slug: + +```php +Route::patch('/songs/{slug}', [SongController::class, 'update']); + +// PATCH /songs/never +// { "slug": "never-gonna-give-you-up", "name": "Never gonna give you up" } + +class SongData extends Data { + #[FromRouteParameter('slug', replaceWhenPresentInPayload: false )] + public string $slug; +} +``` + +Here, `$slug` will be `never-gonna-give-you-up` even though the route parameter value is `never`. + +## Filling properties from the authenticated user + +The `FromCurrentUser` attribute allows filling properties with values from the authenticated user. + +```php +class SongData extends Data { + #[FromAuthenticatedUser] + public UserData $user; +} +``` + +It is possible to specify the guard to use when fetching the user: + +```php +class SongData extends Data { + #[FromAuthenticatedUser('api')] + public UserData $user; +} +``` + +Just like with route parameters, it is possible to fill properties with specific user properties using +`FromAuthenticatedUserProperty`: + +```php +class SongData extends Data { + #[FromAuthenticatedUserProperty('api','name')] + public string $username; +} +``` + +All the other features like custom property mapping and not replacing values when present in the payload are supported +as well. + +## Filling properties from the container + +The `FromContainer` attribute allows filling properties with dependencies from the container. + +```php +class SongData extends Data { + #[FromContainer(SongService::class)] + public SongService $song_service; +} +``` + +When a dependency requires additional parameters these can be provided as such: + +```php +class SongData extends Data { + #[FromContainer(SongService::class, parameters: ['year' => 1984])] + public SongService $song_service; +} +``` + +It is even possible to completely inject the container itself: + +```php +class SongData extends Data { + #[FromContainer] + public Container $container; +} +``` + +Selecting a property from a dependency can be done using `FromContainerProperty`: + +```php +class SongData extends Data { + #[FromContainerProperty(SongService::class, 'name')] + public string $service_name; +} +``` + +Again, all the other features like custom property mapping and not replacing values when present in the payload are +supported as well. + +## Creating your own injectable attributes + +All the attributes we saw earlier implement the `InjectsPropertyValue` interface: + +```php +interface InjectsPropertyValue +{ + public function resolve( + DataProperty $dataProperty, + mixed $payload, + array $properties, + CreationContext $creationContext + ): mixed; + + public function shouldBeReplacedWhenPresentInPayload() : bool; +} +``` + +It is possible to create your own attribute by implementing this interface. The `resolve` method is responsible for +returning the value that should be injected into the property. The `shouldBeReplacedWhenPresentInPayload` method should +return `true` if the value should be replaced when present in the payload. diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/mapping-property-names.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/mapping-property-names.md new file mode 100644 index 0000000..2251ec2 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/mapping-property-names.md @@ -0,0 +1,94 @@ +--- +title: Mapping property names +weight: 7 +--- + +Sometimes the property names in the array from which you're creating a data object might be different. You can define another name for a property when it is created from an array using attributes: + +```php +class ContractData extends Data +{ + public function __construct( + public string $name, + #[MapInputName('record_company')] + public string $recordCompany, + ) { + } +} +``` + +Creating the data object can now be done as such: + +```php +ContractData::from(['name' => 'Rick Astley', 'record_company' => 'RCA Records']); +``` + +Changing all property names in a data object to snake_case in the data the object is created from can be done as such: + +```php +#[MapInputName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +You can also use the `MapName` attribute when you want to combine input (see [transforming data objects](/docs/laravel-data/v4/as-a-resource/mapping-property-names)) and output property name mapping: + +```php +#[MapName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +It is possible to set a default name mapping strategy for all data objects in the `data.php` config file: + +```php +'name_mapping_strategy' => [ + 'input' => SnakeCaseMapper::class, + 'output' => null, +], +``` + + +## Mapping Nested Properties + +You can also map nested properties using dot notation in the `MapInputName` attribute. This is useful when you want to extract a nested value from an array and assign it to a property in your data object: + +```php +class SongData extends Data +{ + public function __construct( + #[MapInputName("title.name")] + public string $title, + #[MapInputName("artists.0.name")] + public string $artist + ) { + } +} +``` + +You can create the data object from an array with nested structures: + +```php +SongData::from([ + "title" => [ + "name" => "Never gonna give you up" + ], + "artists" => [ + ["name" => "Rick Astley"] + ] +]); +``` + +The package has a set of default mappers available, you can find them [here](/docs/laravel-data/v4/advanced-usage/available-property-mappers). diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/model-to-data-object.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/model-to-data-object.md new file mode 100644 index 0000000..0139fcc --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/model-to-data-object.md @@ -0,0 +1,261 @@ +--- +title: From a model +weight: 11 +--- + +It is possible to create a data object from a model, let's say we have the following model: + +```php +class Artist extends Model +{ + +} +``` + +It has the following columns in the database: + +- id +- first_name +- last_name +- created_at +- updated_at + +We can create a data object from this model like this: + +```php +class ArtistData extends Data +{ + public int $id; + public string $first_name; + public string $last_name; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +We now can create a data object from the model like this: + +```php +$artist = ArtistData::from(Artist::find(1)); +``` + +## Casts + +A model can have casts, these casts will be called before a data object is created. Let's extend the model: + +```php +class Artist extends Model +{ + public function casts(): array + { + return [ + 'properties' => 'array' + ]; + } +} +``` + +Within the database the new column will be stored as a JSON string, but in the data object we can just use the array +type: + +```php +class ArtistData extends Data +{ + public int $id; + public string $first_name; + public string $last_name; + public array $properties; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +## Attributes & Accessors + +Laravel allows you to define attributes on a model, these will be called before a data object is created. Let's extend +the model: + +```php +class Artist extends Model +{ + protected function fullName(): Attribute + { + return Attribute::make( + get: fn () => $this->first_name . ' ' . $this->last_name, + ); + } +} +``` + +We now can use the attribute in the data object: + +```php +class ArtistData extends Data +{ + public int $id; + public string $full_name; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +Remember: we need to use the snake_case version of the attribute in the data object since that's how it is stored in the +model. Read on for a more elegant solution when you want to use camelCase property names in your data object. + +It is also possible to define accessors on a model which are the successor of the attributes: + +```php +class Artist extends Model +{ + public function getFullName(): Attribute + { + return Attribute::get(fn () => "{$this->first_name} {$this->last_name}"); + } +} +``` + +With the same data object we created earlier we can now use the accessor. + +## Mapping property names + +Sometimes you want to use camelCase property names in your data object, but the model uses snake_case. You can use +an `MapInputName` to map the property names: + +```php +use Spatie\LaravelData\Attributes\MapInputName; +use Spatie\LaravelData\Mappers\SnakeCaseMapper; + +class ArtistData extends Data +{ + public int $id; + #[MapInputName(SnakeCaseMapper::class)] + public string $fullName; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +An even more elegant solution would be to map every property within the data object: + +```php +#[MapInputName(SnakeCaseMapper::class)] +class ArtistData extends Data +{ + public int $id; + public string $fullName; + public CarbonImmutable $createdAt; + public CarbonImmutable $updatedAt; +} +``` + +## Relations + +Let's create a new model: + +```php +class Song extends Model +{ + public function artist(): BelongsTo + { + return $this->belongsTo(Artist::class); + } +} +``` + +Which has the following columns in the database: + +- id +- artist_id +- title + +We update our previous model as such: + +```php +class Artist extends Model +{ + public function songs(): HasMany + { + return $this->hasMany(Song::class); + } +} +``` + +We can now create a data object like this: + +```php +class SongData extends Data +{ + public int $id; + public string $title; +} +``` + +And update our previous data object like this: + +```php +class ArtistData extends Data +{ + public int $id; + /** @var array */ + public array $songs; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +We can now create a data object with the relations like this: + +```php +$artist = ArtistData::from(Artist::with('songs')->find(1)); +``` + +When you're not loading the relations in advance, `null` will be returned for the relation. + +It is however possible to load the relation on the fly by adding the `LoadRelation` attribute to the property: + +```php +class ArtistData extends Data +{ + public int $id; + /** @var array */ + #[LoadRelation] + public array $songs; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +Now the data object with relations can be created like this: + +```php +$artist = ArtistData::from(Artist::find(1)); +``` + +We even eager-load the relation for performance, neat! + +### Be careful with automatic loading of relations + +Let's update the `SongData` class like this: + +```php +class SongData extends Data +{ + public int $id; + public string $title; + #[LoadRelation] + public ArtistData $artist; +} +``` + +When we now create a data object like this: + +```php +$song = SongData::from(Song::find(1)); +``` + +We'll end up in an infinite loop, since the `SongData` class will try to load the `ArtistData` class, which will try to +load the `SongData` class, and so on. + +## Missing attributes + +When a model is missing attributes and `preventAccessingMissingAttributes` is enabled for a model the `MissingAttributeException` won't be thrown when creating a data object with a property that can be null or Optional. diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/nesting.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/nesting.md new file mode 100644 index 0000000..d1baeb2 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/nesting.md @@ -0,0 +1,166 @@ +--- +title: Nesting +weight: 2 +--- + +It is possible to nest multiple data objects: + +```php +class ArtistData extends Data +{ + public function __construct( + public string $name, + public int $age, + ) { + } +} + +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ArtistData $artist, + ) { + } +} +``` + +You can now create a data object as such: + +```php +new AlbumData( + 'Never gonna give you up', + new ArtistData('Rick Astley', 22) +); +``` + +Or you could create it from an array using a magic creation method: + +```php +AlbumData::from([ + 'title' => 'Never gonna give you up', + 'artist' => [ + 'name' => 'Rick Astley', + 'age' => 22 + ] +]); +``` + +## Collections of data objects + +What if you want to nest a collection of data objects within a data object? + +That's perfectly possible, but there's a small catch; you should always define what kind of data objects will be stored +within the collection. This is really important later on to create validation rules for data objects or partially +transforming data objects. + +There are a few different ways to define what kind of data objects will be stored within a collection. You could use an +annotation, for example, which has an advantage that your IDE will have better suggestions when working with the data +object. And as an extra benefit, static analyzers like PHPStan will also be able to detect errors when your code +is using the wrong types. + +A collection of data objects defined by annotation looks like this: + +```php +/** + * @property \App\Data\SongData[] $songs + */ +class AlbumData extends Data +{ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +or like this when using properties: + +```php +class AlbumData extends Data +{ + public string $title; + + /** @var \App\Data\SongData[] */ + public array $songs; +} +``` + +If you've imported the data class you can use the short notation: + +```php +use App\Data\SongData; + +class AlbumData extends Data +{ + /** @var SongData[] */ + public array $songs; +} +``` + +It is also possible to use generics: + +```php +use App\Data\SongData; + +class AlbumData extends Data +{ + /** @var array */ + public array $songs; +} +``` + +The same is true for Laravel collections, but be sure to use two generic parameters to describe the collection. One for the collection key type and one for the data object type. + +```php +use App\Data\SongData; +use Illuminate\Support\Collection; + +class AlbumData extends Data +{ + /** @var Collection */ + public Collection $songs; +} +``` + +If the collection is well-annotated, the `Data` class doesn't need to use annotations: + +```php +/** + * @template TKey of array-key + * @template TData of \App\Data\SongData + * + * @extends \Illuminate\Support\Collection + */ +class SongDataCollection extends Collection +{ +} + +class AlbumData extends Data +{ + public function __construct( + public string $title, + public SongDataCollection $songs, + ) { + } +} +``` + +You can also use an attribute to define the type of data objects that will be stored within a collection: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public array $songs, + ) { + } +} +``` + +This was the old way to define the type of data objects that will be stored within a collection. It is still supported, but we recommend using the annotation since static analyzers and IDEs will have better support for that. + +```php diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/optional-properties.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/optional-properties.md new file mode 100644 index 0000000..81460ba --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/optional-properties.md @@ -0,0 +1,71 @@ +--- +title: Optional properties +weight: 6 +--- + +Sometimes you have a data object with properties which shouldn't always be set, for example in a partial API update where you only want to update certain fields. In this case you can make a property `Optional` as such: + +```php +use Spatie\LaravelData\Optional; + +class SongData extends Data +{ + public function __construct( + public string $title, + public string|Optional $artist, + ) { + } +} +``` + +You can now create the data object as such: + +```php +SongData::from([ + 'title' => 'Never gonna give you up' +]); +``` + +The value of `artist` will automatically be set to `Optional`. When you transform this data object to an array, it will look like this: + +```php +[ + 'title' => 'Never gonna give you up' +] +``` + +You can manually use `Optional` values within magical creation methods as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string|Optional $artist, + ) { + } + + public static function fromTitle(string $title): static + { + return new self($title, Optional::create()); + } +} +``` + +It is possible to automatically update `Optional` values to `null`: + +```php +class SongData extends Data { + public function __construct( + public string $title, + public Optional|null|string $artist, + ) { + } +} + +SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up']); // artist will `null` instead of `Optional` +``` + +You can read more about this [here](/docs/laravel-data/v4/as-a-data-transfer-object/factories#disabling-optional-values). diff --git a/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/request-to-data-object.md b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/request-to-data-object.md new file mode 100644 index 0000000..53f77f0 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-data-transfer-object/request-to-data-object.md @@ -0,0 +1,108 @@ +--- +title: From a request +weight: 10 +--- + +You can create a data object by the values given in the request. + +For example, let's say you send a POST request to an endpoint with the following data: + +```json +{ + "title" : "Never gonna give you up", + "artist" : "Rick Astley" +} +``` + +This package can automatically resolve a `SongData` object from these values by using the `SongData` class we saw in an +earlier chapter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +You can now inject the `SongData` class in your controller. It will already be filled with the values found in the +request. + +```php +class UpdateSongController +{ + public function __invoke( + Song $model, + SongData $data + ){ + $model->update($data->all()); + + return redirect()->back(); + } +} +``` + +As an added benefit, these values will be validated before the data object is created. If the validation fails, a `ValidationException` will be thrown which will look like you've written the validation rules yourself. + +The package will also automatically validate all requests when passed to the from method: + +```php +class UpdateSongController +{ + public function __invoke( + Song $model, + SongRequest $request + ){ + $model->update(SongData::from($request)->all()); + + return redirect()->back(); + } +} +``` + +We have a complete section within these docs dedicated to validation, you can find it [here](/docs/laravel-data/v4/validation/introduction). + +## Getting the data object filled with request data from anywhere + +You can resolve a data object from the container. + +```php +app(SongData::class); +``` + +We resolve a data object from the container, its properties will already be filled by the values of the request with matching key names. +If the request contains data that is not compatible with the data object, a validation exception will be thrown. + + +## Validating a collection of data objects: + +Let's say we want to create a data object like this from a request: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public DataCollection $songs, + ) { + } +} +``` + +Since the `SongData` has its own validation rules, the package will automatically apply them when resolving validation +rules for this object. + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/_index.md b/_docs/laravel-libs/laravel-data/as-a-resource/_index.md new file mode 100644 index 0000000..153109e --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/_index.md @@ -0,0 +1,5 @@ +--- +title: As a resource + +weight: 4 +--- diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/appending-properties.md b/_docs/laravel-libs/laravel-data/as-a-resource/appending-properties.md new file mode 100644 index 0000000..e6cae89 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/appending-properties.md @@ -0,0 +1,89 @@ +--- +title: Appending properties +weight: 4 +--- + +It is possible to add some extra properties to your data objects when they are transformed into a resource: + +```php +SongData::from(Song::first())->additional([ + 'year' => 1987, +]); +``` + +This will output the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'year' => 1987, +] +``` + +When using a closure, you have access to the underlying data object: + +```php +SongData::from(Song::first())->additional([ + 'slug' => fn(SongData $songData) => Str::slug($songData->title), +]); +``` + +Which produces the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'slug' => 'never-gonna-give-you-up', +] +``` + +It is also possible to add extra properties by overwriting the `with` method within your data object: + +```php +class SongData extends Data +{ + public function __construct( + public int $id, + public string $title, + public string $artist + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + $song->id, + $song->title, + $song->artist + ); + } + + public function with() + { + return [ + 'endpoints' => [ + 'show' => action([SongsController::class, 'show'], $this->id), + 'edit' => action([SongsController::class, 'edit'], $this->id), + 'delete' => action([SongsController::class, 'delete'], $this->id), + ] + ]; + } +} +``` + +Now each transformed data object contains an `endpoints` key with all the endpoints for that data object: + +```php +[ + 'id' => 1, + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'endpoints' => [ + 'show' => 'https://spatie.be/songs/1', + 'edit' => 'https://spatie.be/songs/1', + 'delete' => 'https://spatie.be/songs/1', + ], +] +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-array.md b/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-array.md new file mode 100644 index 0000000..58138df --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-array.md @@ -0,0 +1,126 @@ +--- +title: From data to array +weight: 1 +--- + +A data object can automatically be transformed into an array as such: + +```php +SongData::from(Song::first())->toArray(); +``` + +Which will output the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley' +] +``` + +By default, calling `toArray` on a data object will recursively transform all properties to an array. This means that nested data objects and collections of data objects will also be transformed to arrays. Other complex types like `Carbon`, `DateTime`, `Enums`, etc... will be transformed into a string. We'll see in the [transformers](/docs/laravel-data/v4/as-a-resource/transformers) section how to configure and customize this behavior. + +If you only want to transform a data object to an array without transforming the properties, you can call the `all` method: + +```php +SongData::from(Song::first())->all(); +``` + +You can also manually transform a data object to JSON: + +```php +SongData::from(Song::first())->toJson(); +``` + +## Using collections + +Here's how to create a collection of data objects: + +```php +SongData::collect(Song::all()); +``` + +A collection can be transformed to array: + +```php +SongData::collect(Song::all())->toArray(); +``` + +Which will output the following array: + +```php +[ + [ + "name": "Never Gonna Give You Up", + "artist": "Rick Astley" + ], + [ + "name": "Giving Up on Love", + "artist": "Rick Astley" + ] +] +``` + +## Nesting + +It is possible to nest data objects. + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public string $email, + public SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + $user->email, + SongData::from($user->favorite_song) + ); + } +} +``` + +When transformed to an array, this will look like the following: + +```php +[ + "name": "Ruben", + "email": "ruben@spatie.be", + "favorite_song": [ + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + ] +] +``` + +You can also nest a collection of data objects: + +```php +class AlbumData extends Data +{ + /** + * @param Collection $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + SongData::collect($album->songs) + ); + } +} +``` + +As always, remember to type collections of data objects by annotation or the `DataCollectionOf` attribute, this is essential to transform these collections correctly. diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-resource.md b/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-resource.md new file mode 100644 index 0000000..8ec323e --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/from-data-to-resource.md @@ -0,0 +1,202 @@ +--- +title: From data to resource +weight: 2 +--- + +A data object will automatically be transformed to a JSON response when returned in a controller: + +```php +class SongController +{ + public function show(Song $model) + { + return SongData::from($model); + } +} +``` + +The JSON then will look like this: + +```json +{ + "name": "Never gonna give you up", + "artist": "Rick Astley" +} +``` + +### Collections + +Returning a data collection from the controller like this: + +```php +SongData::collect(Song::all()); +``` + +Will return a collection automatically transformed to JSON: + +```json +[ + { + "name": "Never Gonna Give You Up", + "artist": "Rick Astley" + }, + { + "name": "Giving Up on Love", + "artist": "Rick Astley" + } +] +``` + +### Paginators + +It is also possible to provide a paginator: + +```php +SongData::collect(Song::paginate()); +``` + +The data object is smart enough to create a paginated response from this with links to the next, previous, last, ... pages: + +```json +{ + "data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ], + "meta" : { + "current_page": 1, + "first_page_url": "https://spatie.be/?page=1", + "from": 1, + "last_page": 7, + "last_page_url": "https://spatie.be/?page=7", + "next_page_url": "https://spatie.be/?page=2", + "path": "https://spatie.be/", + "per_page": 15, + "prev_page_url": null, + "to": 15, + "total": 100 + } +} +``` + + +## Transforming empty objects + +When creating a new model, you probably want to provide a blueprint to the frontend with the required data to create a model. For example: + +```json +{ + "name": null, + "artist": null +} +``` + +You could make each property of the data object nullable like this: + +```php +class SongData extends Data +{ + public function __construct( + public ?string $title, + public ?string $artist, + ) { + } + + // ... +} +``` + +This approach would work, but as soon as the model is created, the properties won't be `null`, which doesn't follow our data model. So it is considered a bad practice. + +That's why in such cases, you can return an empty representation of the data object: + +```php +class SongsController +{ + public function create(): array + { + return SongData::empty(); + } +} +``` + +Which will output the following JSON: + +```json +{ + "name": null, + "artist": null +} +``` + +The `empty` method on a data object will return an array with default empty values for the properties in the data object. + +It is possible to change the default values within this array by providing them in the constructor of the data object: + + ```php + class SongData extends Data +{ + public function __construct( + public string $title = 'Title of the song here', + public string $artist = "An artist", + ) { + } + + // ... +} + ``` + +Now when we call `empty`, our JSON looks like this: + +```json +{ + "name": "Title of the song here", + "artist": "An artist" +} +``` + +You can also pass defaults within the `empty` call: + +```php +SongData::empty([ + 'name' => 'Title of the song here', + 'artist' => 'An artist' +]); +``` + +Or filter the properties that should be included in the empty response: + +```php +SongData::empty(only: ['name']); // Will only return the `name` property + +SongData::empty(except: ['name']); // Will return the `artist` property +``` + +## Response status code + +When a resource is being returned from a controller, the status code of the response will automatically be set to `201 CREATED` when Laravel data detects that the request's method is `POST`. In all other cases, `200 OK` will be returned. + +## Resource classes + +To make it a bit more clear that a data object is a resource, you can use the `Resource` class instead of the `Data` class: + +```php +use Spatie\LaravelData\Resource; + +class SongResource extends Resource +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +These resource classes have as an advantage that they won't validate data or check authorization, They are only used to transform data which makes them a bit faster. diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/lazy-properties.md b/_docs/laravel-libs/laravel-data/as-a-resource/lazy-properties.md new file mode 100644 index 0000000..e02416b --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/lazy-properties.md @@ -0,0 +1,568 @@ +--- +title: Including and excluding properties +weight: 6 +--- + +Sometimes you don't want all the properties included when transforming a data object to an array, for example: + +```php +class AlbumData extends Data +{ + /** + * @param Collection $songs + */ + public function __construct( + public string $title, + public Collection $songs, + ) { + } +} +``` + +This will always output a collection of songs, which can become quite large. With lazy properties, we can include +properties when we want to: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + Lazy::create(fn() => SongData::collect($album->songs)) + ); + } +} +``` + +The `songs` key won't be included in the resource when transforming it from a model. Because the closure that provides +the data won't be called when transforming the data object unless we explicitly demand it. + +Now when we transform the data object as such: + +```php +AlbumData::from(Album::first())->toArray(); +``` + +We get the following array: + +```php +[ + 'title' => 'Together Forever', +] +``` + +As you can see, the `songs` property is missing in the array output. Here's how you can include it. + +```php +AlbumData::from(Album::first())->include('songs'); +``` + +## Including lazy properties + +Lazy properties will only be included when the `include` method is called on the data object with the property's name. + +It is also possible to nest these includes. For example, let's update the `SongData` class and make all of its +properties lazy: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::create(fn() => $song->title), + Lazy::create(fn() => $song->artist) + ); + } +} +``` + +Now `name` or `artist` should be explicitly included. This can be done as such on the `AlbumData`: + +```php +AlbumData::from(Album::first())->include('songs.name', 'songs.artist'); +``` + +Or you could combine these includes: + +```php +AlbumData::from(Album::first())->include('songs.{name, artist}'); +``` + +If you want to include all the properties of a data object, you can do the following: + +```php +AlbumData::from(Album::first())->include('songs.*'); +``` + +Explicitly including properties of data objects also works on a single data object. For example, our `UserData` looks +like this: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + Lazy::create(fn() => SongData::from($user->favorite_song)) + ); + } +} +``` + +We can include properties of the data object just like we would with collections of data objects: + +```php +return UserData::from(Auth::user())->include('favorite_song.name'); +``` + +## Types of Lazy properties + +### Conditional Lazy properties + +You can include lazy properties in different ways: + +```php +Lazy::create(fn() => SongData::collect($album->songs)); +``` + +With a basic `Lazy` property, you must explicitly include it when the data object is transformed. + +Sometimes you only want to include a property when a specific condition is true. This can be done with conditional lazy +properties: + +```php +Lazy::when(fn() => $this->is_admin, fn() => SongData::collect($album->songs)); +``` + +The property will only be included when the `is_admin` property of the data object is true. It is not possible to +include the property later on with the `include` method when a condition is not accepted. + +### Relational Lazy properties + +You can also only include a lazy property when a particular relation is loaded on the model as such: + +```php +Lazy::whenLoaded('songs', $album, fn() => SongData::collect($album->songs)); +``` + +Now the property will only be included when the song's relation is loaded on the model. + +## Default included lazy properties + +It is possible to mark a lazy property as included by default: + +```php +Lazy::create(fn() => SongData::collect($album->songs))->defaultIncluded(); +``` + +The property will now always be included when the data object is transformed. You can explicitly exclude properties that +were default included as such: + +```php +AlbumData::create(Album::first())->exclude('songs'); +``` + +## Auto Lazy + +Writing Lazy properties can be a bit cumbersome. It is often a repetitive task to write the same code over and over +again while the package can infer almost everything. + +Let's take a look at our previous example: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + Lazy::create(fn() => SongData::from($user->favorite_song)) + ); + } +} +``` + +The package knows how to get the property from the model and wrap it into a data object, but since we're using a lazy +property, we need to write our own magic creation method with a lot of repetitive code. + +In such a situation auto lazy might be a good fit, instead of casting the property directly into the data object, the +casting process is wrapped in a lazy Closure. + +This makes it possible to rewrite the example as such: + +```php +#[AutoLazy] +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +While achieving the same result! + +Auto Lazy wraps the casting process of a value for every property typed as `Lazy` into a Lazy Closure when the +`AutoLazy` attribute is present on the class. + +It is also possible to use the `AutoLazy` attribute on a property level: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoLazy] + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +The auto lazy process won't be applied in the following situations: + +- When a null value is passed to the property +- When the property value isn't present in the input payload and the property typed as `Optional` +- When a Lazy Closure is passed to the property + +### Auto lazy with model relations + +When you're constructing a data object from an Eloquent model, it is also possible to automatically create lazy +properties for model relations which are only resolved when the relation is loaded: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy] + public Lazy|SongData $favoriteSong, + ) { + } +} +``` + +When the `favoriteSong` relation is loaded on the model, the property will be included in the data object. + +If the name of the relation doesn't match the property name, you can specify the relation name: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy('favoriteSong')] + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +The package will use the regular casting process when the relation is loaded, so it is also perfectly possible to create a collection of data objects: + +```php +class UserData extends Data +{ + /** + * @param Lazy|array $favoriteSongs + */ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy] + public Lazy|array $favoriteSongs, + ) { + } +} +``` + +## Only and Except + +Lazy properties are great for reducing payloads sent over the wire. However, when you completely want to remove a +property Laravel's `only` and `except` methods can be used: + +```php +AlbumData::from(Album::first())->only('songs'); // will only show `songs` +AlbumData::from(Album::first())->except('songs'); // will show everything except `songs` +``` + +It is also possible to use multiple keys: + +```php +AlbumData::from(Album::first())->only('songs.name', 'songs.artist'); +AlbumData::from(Album::first())->except('songs.name', 'songs.artist'); +``` + +And special keys like described above: + +```php +AlbumData::from(Album::first())->only('songs.{name, artist}'); +AlbumData::from(Album::first())->except('songs.{name, artist}'); +``` + +Only and except always take precedence over include and exclude, which means that when a property is hidden by `only` or +`except` it is impossible to show it again using `include`. + +### Conditionally + +It is possible to add an `include`, `exclude`, `only` or `except` if a certain condition is met: + +```php +AlbumData::from(Album::first())->includeWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->excludeWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->onlyWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->except('songs', auth()->user()->isAdmin); +``` + +You can also use the values of the data object in such condition: + +```php +AlbumData::from(Album::first())->includeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->excludeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->onlyWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->exceptWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +``` + +In some cases, you may want to define an include on a class level by implementing a method: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs' => $this->title === 'Together Forever', + ]; + } +} +``` + +It is even possible to include nested properties: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs.title' => $this->title === 'Together Forever', + ]; + } +} +``` + +You can define exclude, except and only partials on a data class: + +- You can define **excludes** in a `excludeProperties` method +- You can define **except** in a `exceptProperties` method +- You can define **only** in a `onlyProperties` method + +## Using query strings + +It is possible to include or exclude lazy properties by the URL query string: + +For example, when we create a route `my-account`: + +```php +// in web.php + +Route::get('my-account', fn() => UserData::from(User::first())); +``` + +We now specify that a key of the data object is allowed to be included by query string on the data object: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return ['favorite_song']; + } + + // ... +} +``` + +Our JSON would look like this when we request `https://spatie.be/my-account`: + +```json +{ + "name" : "Ruben Van Assche" +} +``` + +We can include `favorite_song` by adding it to the query in the URL as such: + +``` +https://spatie.be/my-account?include=favorite_song +``` + +```json +{ + "name" : "Ruben Van Assche", + "favorite_song" : { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + } +} +``` + +We can also include multiple properties by separating them with a comma: + +``` +https://spatie.be/my-account?include=favorite_song,favorite_movie +``` + +Or by using a group input: + +``` +https://spatie.be/my-account?include[]=favorite_song&include[]=favorite_movie +``` + +Including properties works for data objects and data collections. + +### Allowing includes by query string + +By default, it is disallowed to include properties by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return []; + } +} +``` + +You can pass several names of properties which are allowed to be included by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return ['favorite_song', 'name']; + } +} +``` + +Or you can allow all properties to be included by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return null; + } +} +``` + +### Other operations + +It is also possible to run exclude, except and only operations on a data object: + +- You can define **excludes** in `allowedRequestExcludes` and use the `exclude` key in your query string +- You can define **except** in `allowedRequestExcept` and use the `except` key in your query string +- You can define **only** in `allowedRequestOnly` and use the `only` key in your query string + +## Mutability + +Adding includes/excludes/only/except to a data object will only affect the data object (and its nested chain) once: + +```php +AlbumData::from(Album::first())->include('songs')->toArray(); // will include songs +AlbumData::from(Album::first())->toArray(); // will not include songs +``` + +If you want to add includes/excludes/only/except to a data object and its nested chain that will be used for all future +transformations, you can define them in their respective *properties methods: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs' + ]; + } +} +``` + +Or use the permanent methods: + +```php +AlbumData::from(Album::first())->includePermanently('songs'); +AlbumData::from(Album::first())->excludePermanently('songs'); +AlbumData::from(Album::first())->onlyPermanently('songs'); +AlbumData::from(Album::first())->exceptPermanently('songs'); +``` + +When using a conditional includes/excludes/only/except, you can set the permanent flag: + +```php +AlbumData::from(Album::first())->includeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +AlbumData::from(Album::first())->excludeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +AlbumData::from(Album::first())->onlyWhen('songs', fn(AlbumData $data) => count($data->songs) > 0), permanent: true); +AlbumData::from(Album::first())->except('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/mapping-property-names.md b/_docs/laravel-libs/laravel-data/as-a-resource/mapping-property-names.md new file mode 100644 index 0000000..c21faff --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/mapping-property-names.md @@ -0,0 +1,84 @@ +--- +title: Mapping property names +weight: 3 +--- + +Sometimes you might want to change the name of a property in the transformed payload, with attributes this is possible: + +```php +class ContractData extends Data +{ + public function __construct( + public string $name, + #[MapOutputName('record_company')] + public string $recordCompany, + ) { + } +} +``` + +Now our array looks like this: + +```php +[ + 'name' => 'Rick Astley', + 'record_company' => 'RCA Records', +] +``` + +Changing all property names in a data object to snake_case as output data can be done as such: + +```php +#[MapOutputName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +You can also use the `MapName` attribute when you want to combine input and output property name mapping: + +```php +#[MapName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +It is possible to set a default name mapping strategy for all data objects in the `data.php` config file: + +```php +'name_mapping_strategy' => [ + 'input' => null, + 'output' => SnakeCaseMapper::class, +], +``` + +You can now create a data object as such: + +```php +$contract = new ContractData( + name: 'Rick Astley', + recordCompany: 'RCA Records', +); +``` + +And a transformed version of the data object will look like this: + +```php +[ + 'name' => 'Rick Astley', + 'record_company' => 'RCA Records', +] +``` + +The package has a set of default mappers available, you can find them [here](/docs/laravel-data/v4/advanced-usage/available-property-mappers). diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/transformers.md b/_docs/laravel-libs/laravel-data/as-a-resource/transformers.md new file mode 100644 index 0000000..7d778b4 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/transformers.md @@ -0,0 +1,195 @@ +--- +title: Transforming data +weight: 7 +--- + +Transformers allow you to transform complex types to simple types. This is useful when you want to transform a data object to an array or JSON. + +No complex transformations are required for the default types (string, bool, int, float, enum and array), but special types like `Carbon` or a Laravel Model will need extra attention. + +Transformers are simple classes that will convert a such complex types to something simple like a `string` or `int`. For example, we can transform a `Carbon` object to `16-05-1994`, `16-05-1994T00:00:00+00` or something completely different. + +There are two ways you can define transformers: locally and globally. + +## Local transformers + +When you want to transform a specific property, you can use an attribute with the transformer you want to use: + +```php +class ArtistData extends Data{ + public function __construct( + public string $name, + #[WithTransformer(DateTimeInterfaceTransformer::class)] + public Carbon $birth_date + ) { + } +} +``` + +The `DateTimeInterfaceTransformer` is shipped with the package and will transform objects of type `Carbon`, `CarbonImmutable`, `DateTime` and `DateTimeImmutable` to a string. + +The format used for converting the date to string can be set in the `data.php` config file. It is also possible to manually define a format: + +```php +class ArtistData extends Data{ + public function __construct( + public string $name, + #[WithTransformer(DateTimeInterfaceTransformer::class, format: 'm-Y')] + public Carbon $birth_date + ) { + } +} +``` + +Next to a `DateTimeInterfaceTransformer` the package also ships with an `ArrayableTransformer` that transforms an `Arrayable` object to an array. + +It is possible to create transformers for your specific types. You can find more info [here](/docs/laravel-data/v4/advanced-usage/creating-a-transformer). + +## Global transformers + +Global transformers are defined in the `data.php` config file and are used when no local transformer for a property was added. By default, there are two transformers: + +```php +use Illuminate\Contracts\Support\Arrayable; +use Spatie\LaravelData\Transformers\ArrayableTransformer; +use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer; + +/* + * Global transformers will take complex types and transform them into simple + * types. + */ +'transformers' => [ + DateTimeInterface::class => DateTimeInterfaceTransformer::class, + Arrayable::class => ArrayableTransformer::class, +], +``` + +The package will look through these global transformers and tries to find a suitable transformer. You can define transformers for: + +- a **specific implementation** (e.g. CarbonImmutable) +- an **interface** (e.g. DateTimeInterface) +- a **base class** (e.g. Enum) + +## Getting a data object without transforming + +It is possible to get an array representation of a data object without transforming the properties. This means `Carbon` objects won't be transformed into strings. And also, nested data objects and `DataCollection`s won't be transformed into arrays. You can do this by calling the `all` method on a data object like this: + +```php +ArtistData::from($artist)->all(); +``` + +## Getting a data object (on steroids) + +Internally the package uses the `transform` method for operations like `toArray`, `all`, `toJson` and so on. This method is highly configurable, when calling it without any arguments it will behave like the `toArray` method: + +```php +ArtistData::from($artist)->transform(); +``` + +Producing the following result: + +```php +[ + 'name' => 'Rick Astley', + 'birth_date' => '06-02-1966', +] +``` + +It is possible to disable the transformation of values, which will make the `transform` method behave like the `all` method: + +```php +use Spatie\LaravelData\Support\Transformation\TransformationContext; + +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withoutValueTransformation() +); +``` + +Outputting the following array: + +```php +[ + 'name' => 'Rick Astley', + 'birth_date' => Carbon::parse('06-02-1966'), +] +``` + +The [mapping of property names](/docs/laravel-data/v4/as-a-resource/mapping-property-names) can also be disabled: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withoutPropertyNameMapping() +); +``` + +It is possible to enable [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping-data) the data object: + +```php +use Spatie\LaravelData\Support\Wrapping\WrapExecutionType; + +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withWrapping() +); +``` + +Outputting the following array: + +```php +[ + 'data' => [ + 'name' => 'Rick Astley', + 'birth_date' => '06-02-1966', + ], +] +``` + +You can also add additional global transformers as such: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withGlobalTransformer( + 'string', + StringToUpperTransformer::class + ) +); +``` + +## Transformation depth + +When transforming a complicated structure of nested data objects it is possible that an infinite loop is created of data objects including each other. +To prevent this, a transformation depth can be set, when that depth is reached when transforming, either an exception will be thrown or an empty +array is returned, stopping the transformation. + +This transformation depth can be set globally in the `data.php` config file: + +```php +'max_transformation_depth' => 20, +``` + +Setting the transformation depth to `null` will disable the transformation depth check: + +```php +'max_transformation_depth' => null, +``` + +It is also possible if a `MaxTransformationDepthReached` exception should be thrown or an empty array should be returned: + +```php +'throw_when_max_transformation_depth_reached' => true, +``` + +It is also possible to set the transformation depth on a specific transformation by using a `TransformationContextFactory`: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->maxDepth(20) +); +``` + +By default, an exception will be thrown when the maximum transformation depth is reached. This can be changed to return an empty array as such: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->maxDepth(20, throw: false) +); +``` diff --git a/_docs/laravel-libs/laravel-data/as-a-resource/wrapping.md b/_docs/laravel-libs/laravel-data/as-a-resource/wrapping.md new file mode 100644 index 0000000..995c256 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/as-a-resource/wrapping.md @@ -0,0 +1,225 @@ +--- +title: Wrapping +weight: 5 +--- + +By default, when a data object is transformed into JSON in your controller, it looks like this: + +```json +{ + "name" : "Never gonna give you up", + "artist" : "Rick Astley" +} +``` + +It is possible to wrap a data object: + +```php +SongData::from(Song::first())->wrap('data'); +``` + +Now the JSON looks like this: + +```json +{ + "data" : { + "name" : "Never gonna give you up", + "artist" : "Rick Astley" + } +} +``` + +Data objects and collections will only get wrapped when you're sending them as a response and never when calling `toArray` or `toJson` on it. + +It is possible to define a default wrap key inside a data object: + +```php +class SongData extends Data +{ + public function defaultWrap(): string + { + return 'data'; + } + + // ... +} +``` + +Or you can set a global wrap key inside the `data.php` config file: + +```php + /* + * Data objects can be wrapped into a key like 'data' when used as a resource, + * this key can be set globally here for all data objects. You can pass in + * `null` if you want to disable wrapping. + */ + 'wrap' => 'data', +``` + +## Wrapping collections + +Collections can be wrapped just like data objects: + +```php +SongData::collect(Song::all(), DataCollection::class)->wrap('data'); +``` + +Notice here, for now we only support wrapping `DataCollections`, `PaginatedDataCollections` and `CursorPaginatedDataCollections` on the root level. Wrapping won't work for Laravel Collections or arrays (for now) since the package cannot interfere. Nested properties with such types can be wrapped though (see further). + +The JSON will now look like this: + +```json +{ + "data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ] +} +``` + +It is possible to set the data key in paginated collections: + +```php +SongData::collect(Song::paginate(), PaginatedDataCollection::class)->wrap('paginated_data'); +``` + +Which will let the JSON look like this: + +```json +{ + "paginated_data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ], + "meta" : { + "current_page" : 1, + "first_page_url" : "https://spatie.be/?page=1", + "from" : 1, + "last_page" : 7, + "last_page_url" : "https://spatie.be/?page=7", + "next_page_url" : "https://spatie.be/?page=2", + "path" : "https://spatie.be/", + "per_page" : 15, + "prev_page_url" : null, + "to" : 15, + "total" : 100 + } +} +``` + +## Nested wrapping + +A data object included inside another data object will never be wrapped even if a wrap is set: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public string $email, + public SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + $user->email, + SongData::create($user->favorite_song)->wrap('data') + ); + } +} + +UserData::from(User::first())->wrap('data'); +``` + +```json +{ + "data" : { + "name" : "Ruben", + "email" : "ruben@spatie.be", + "favorite_song" : { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + } + } +} +``` + +A data collection inside a data object will get wrapped when a wrapping key is set (in order to mimic Laravel resources): + +```php +use Spatie\LaravelData\Attributes\DataCollectionOf; +use Spatie\LaravelData\DataCollection; + +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public DataCollection $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + SongData::collect($album->songs, DataCollection::class)->wrap('data') + ); + } +} + +AlbumData::from(Album::first())->wrap('data'); +``` + +The JSON will look like this: + +```json +{ + "data" : { + "title" : "Whenever You Need Somebody", + "songs": { + "data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ] + } + } +} +``` + +## Disabling wrapping + +Whenever a data object is wrapped due to the default wrap method or a global wrap key, it is possible to disable wrapping on a data object/collection: + +```php +SongData::from(Song::first())->withoutWrapping(); +``` + +## Getting a wrapped array + +By default, `toArray` and `toJson` will never wrap a data object or collection, but it is possible to get a wrapped array: + +```php +SongData::from(Song::first())->wrap('data')->transform(wrapExecutionType: WrapExecutionType::Enabled); +``` diff --git a/_docs/laravel-libs/laravel-data/changelog.md b/_docs/laravel-libs/laravel-data/changelog.md new file mode 100644 index 0000000..dc9856e --- /dev/null +++ b/_docs/laravel-libs/laravel-data/changelog.md @@ -0,0 +1,6 @@ +--- +title: Changelog +weight: 7 +--- + +All notable changes to laravel-data are documented [on GitHub](https://github.com/spatie/laravel-data/blob/main/CHANGELOG.md) diff --git a/_docs/laravel-libs/laravel-data/getting-started/_index.md b/_docs/laravel-libs/laravel-data/getting-started/_index.md new file mode 100644 index 0000000..84d5ab4 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/getting-started/_index.md @@ -0,0 +1,4 @@ +--- +title: Getting started +weight: 1 +--- diff --git a/_docs/laravel-libs/laravel-data/getting-started/quickstart.md b/_docs/laravel-libs/laravel-data/getting-started/quickstart.md new file mode 100644 index 0000000..5b89492 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/getting-started/quickstart.md @@ -0,0 +1,1028 @@ +--- +title: Quickstart +weight: 1 +--- + +In this quickstart, we'll guide you through the most important functionalities of the package and how to use them. + +First, you should [install the package](/docs/laravel-data/v4/installation-setup). + +We will create a blog with different posts, so let's start with the `PostData` object. A post has a title, some content, a status and a date when it was published: + +```php +use Spatie\LaravelData\Data; + +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + public ?CarbonImmutable $published_at + ) { + } +} +``` + +Extending your data objects from the base `Data` object is the only requirement for using the package. We add the requirements for a post as public properties. + +The `PostStatus` is a native enum: + +```php +enum PostStatus: string +{ + case draft = 'draft'; + case published = 'published'; + case archived = 'archived'; +} +``` + +We store this `PostData` object as `app/Data/PostData.php`, so we have all our data objects bundled in one directory, but you're free to store them wherever you want within your application. + +Tip: you can also quickly make a data object using the CLI: `php artisan make:data Post`, it will create a file `app/Data/PostData.php`. + +We can now create a `PostData` object just like any plain PHP object: + +```php +$post = new PostData( + 'Hello laravel-data', + 'This is an introduction post for the new package', + PostStatus::published, + CarbonImmutable::now() +); +``` + +The package also allows you to create these data objects from any type, for example, an array: + +```php +$post = PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'published_at' => CarbonImmutable::now(), +]); +``` + +Or a `Post` model with the required properties: + +```php +class Post extends Model +{ + protected $guarded = []; + + protected $casts = [ + 'status' => PostStatus::class, + 'published_at' => 'immutable_datetime', + ]; +} +``` + +Can be quickly transformed into a `PostData` object: + +```php +PostData::from(Post::findOrFail($id)); +``` + +## Using requests + +Let's say we have a Laravel request coming from the frontend with these properties. Our controller would then validate these properties, and then it would store them in a model; this can be done as such: + +```php +class DataController +{ + public function __invoke(Request $request) + { + $request->validate($this->rules()); + + $postData = PostData::from([ + 'title' => $request->input('title'), + 'content' => $request->input('content'), + 'status' => $request->enum('status', PostStatus::class), + 'published_at' => $request->has('published_at') + ? CarbonImmutable::createFromFormat(DATE_ATOM, $request->input('published_at')) + : null, + ]); + + Post::create($postData->toArray()); + + return redirect()->back(); + } + + private function rules(): array + { + return [ + 'title' => ['required', 'string'], + 'content' => ['required', 'string'], + 'status' => ['required', new Enum(PostStatus::class)], + 'published_at' => ['nullable', 'date'], + ]; + } +} +``` + +That's a lot of code to fill a data object, using laravel data we can remove a lot of code: + +```php +class DataController +{ + public function __invoke(PostData $postData) + { + Post::create($postData->toArray()); + + return redirect()->back(); + } +} +``` + +Let's see what's happening: + +1) Laravel boots up, and the router directs to the `DataController` +2) Because we're injecting `PostData`, two things happen + - `PostData` will generate validation rules based on the property types and validate the request + - The `PostData` object is automatically created from the request +3) We're now in the `__invoke` method with a valid `PostData` object + +You can always check the generated validation rules of a data object like this: + +```php +class DataController +{ + public function __invoke(Request $request) + { + dd(PostData::getValidationRules($request->toArray())); + } +} +``` + +Which provides us with the following set of rules: + +```php +array:4 [ + "title" => array:2 [ + 0 => "required" + 1 => "string" + ] + "content" => array:2 [ + 0 => "required" + 1 => "string" + ] + "status" => array:2 [ + 0 => "required" + 1 => Illuminate\Validation\Rules\Enum { + #type: "App\Enums\PostStatus" + } + ] + "published_at" => array:1 [ + 0 => "nullable" + ] +] +``` + +As you can see, we're missing the `date` rule on the `published_at` property. By default, this package will automatically generate the following rules: + +- `required` when a property cannot be `null` +- `nullable` when a property can be `null` +- `numeric` when a property type is `int` +- `string` when a property type is `string` +- `boolean` when a property type is `bool` +- `numeric` when a property type is `float` +- `array` when a property type is `array` +- `enum:*` when a property type is a native enum + +You can read more about the process of automated rule generation [here](/docs/laravel-data/v4/as-a-data-transfer-object/request-to-data-object#content-automatically-inferring-rules-for-properties-1). + +We can easily add the date rule by using an attribute to our data object: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +Now our validation rules look like this: + +```php +array:4 [ + "title" => array:2 [ + 0 => "required" + 1 => "string" + ] + "content" => array:2 [ + 0 => "required" + 1 => "string" + ] + "status" => array:2 [ + 0 => "required" + 1 => Illuminate\Validation\Rules\Enum { + #type: "App\Enums\PostStatus" + } + ] + "published_at" => array:2 [ + 0 => "nullable" + 1 => "date" + ] +] +``` + +There are [tons](/docs/laravel-data/v4/advanced-usage/validation-attributes) of validation rule attributes you can add to data properties. There's still much more you can do with validating data objects. Read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/request-to-data-object#validating-a-request). + +Tip: By default, when creating a data object in a non request context, no validation is executed: + +```php +$post = PostData::from([ + // As long as PHP accepts the values for the properties, the object will be created +]); +``` + +You can create validated objects without requests like this: + +```php +$post = PostData::validateAndCreate([ + // Before creating the object, each value will be validated +]); +``` + +## Casting data + +Let's send the following payload to the controller: + +```json +{ + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "published_at" : "2021-09-24T13:31:20+00:00" +} +``` + +We get the `PostData` object populated with the values in the JSON payload, neat! But how did the package convert the `published_at` string into a `CarbonImmutable` object? + +It is possible to define casts within the `data.php` config file. By default, the casts list looks like this: + +```php +'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, +], +``` + +This code means that if a class property is of type `DateTime`, `Carbon`, `CarbonImmutable`, ... it will be automatically cast. + +You can create your own casts; read more about it [here](/docs/laravel-data/v4/advanced-usage/creating-a-cast). + +### Local casts + +Sometimes you need one specific cast in one specific data object; in such a case defining a local cast specific for the data object is a good option. + +Let's say we have an `Image` class: + +```php +class Image +{ + public function __construct( + public string $file, + public int $size, + ) { + } +} +``` + +There are two options how an `Image` can be created: + +a) From a file upload +b) From an array when the image has been stored in the database + +Let's create a cast for this: + +```php +use Illuminate\Http\UploadedFile; +use Spatie\LaravelData\Casts\Cast; +use Spatie\LaravelData\Casts\Uncastable; +use Spatie\LaravelData\Support\DataProperty; +use Str; + +class ImageCast implements Cast +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): Image|Uncastable + { + // Scenario A + if ($value instanceof UploadedFile) { + $filename = $value->store('images', 'public'); + + return new Image( + $filename, + $value->getSize(), + ); + } + + // Scenario B + if (is_array($value)) { + return new Image( + $value['filename'], + $value['size'], + ); + } + + return Uncastable::create(); + } +} + +``` + +Ultimately, we return `Uncastable`, telling the package to try other casts (if available) because this cast cannot cast the value. + +The last thing we need to do is add the cast to our property. We use the `WithCast` attribute for this: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +You can read more about casting [here](/docs/laravel-data/v4/as-a-data-transfer-object/casts). + +## Customizing the creation of a data object + +We've seen the powerful `from` method on data objects, you can throw anything at it, and it will cast the value into a data object. But what if it can't cast a specific type, or what if you want to change how a type is precisely cast into a data object? + +It is possible to manually define how a type is converted into a data object. What if we would like to support to create posts via an email syntax like this: + +``` +title|status|content +``` + +Creating a `PostData` object would then look like this: + +```php +PostData::from('Hello laravel-data|draft|This is an introduction post for the new package'); +``` + +To make this work, we need to add a magic creation function within our data class: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } + + public static function fromString(string $post): PostData + { + $fields = explode('|', $post); + + return new self( + $fields[0], + $fields[2], + PostStatus::from($fields[1]), + null, + null + ); + } +} +``` + +Magic creation methods allow you to create data objects from any type by passing them to the `from` method of a data +object, you can read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object#content-magical-creation). + +It can be convenient to transform more complex models than our `Post` into data objects because you can decide how a model +would be mapped onto a data object. + +## Nesting data objects and arrays of data objects + +Now that we have a fully functional post-data object. We're going to create a new data object, `AuthorData`, that will store the name of an author and an array of posts the author wrote: + +```php +use Spatie\LaravelData\Attributes\DataCollectionOf; + +class AuthorData extends Data +{ + /** + * @param array $posts + */ + public function __construct( + public string $name, + public array $posts + ) { + } +} +``` + +Notice that we've typed the `$posts` property as an array of `PostData` objects using a docblock. This will be very useful later on! The package always needs to know what type of data objects are stored in an array. Of course, when you're storing other types then data objects this is not required but recommended. + +We can now create an author object as such: + +```php +new AuthorData( + 'Ruben Van Assche', + PostData::collect([ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::draft, + ], + [ + 'title' => 'What is a data object', + 'content' => 'How does it work', + 'status' => PostStatus::published, + ], + ]) +); +``` + +As you can see, the `collect` method can create an array of the `PostData` objects. + +But there's another way; thankfully, our `from` method makes this process even more straightforward: + +```php +AuthorData::from([ + 'name' => 'Ruben Van Assche', + 'posts' => [ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::draft, + ], + [ + 'title' => 'What is a data object', + 'content' => 'How does it work', + 'status' => PostStatus::published, + ], + ], +]); +``` + +The data object is smart enough to convert an array of posts into an array of post data. Mapping data coming from the front end was never that easy! + +### Nesting objects + +Nesting an individual data object into another data object is perfectly possible. Remember the `Image` class we created? We needed a cast for it, but it is a perfect fit for a data object; let's create it: + +```php +class ImageData extends Data +{ + public function __construct( + public string $filename, + public string $size, + ) { + } + + public static function fromUploadedImage(UploadedFile $file): self + { + $stored = $file->store('images', 'public'); + + return new ImageData( + url($stored), + $file->getSize(), + ); + } +} +``` + +In our `ImageCast`, the image could be created from a file upload or an array; we'll handle that first case with the `fromUploadedImage` magic method. Because `Image` is now `ImageData,` the second case is automatically handled by the package, neat! + +We'll update our `PostData` object as such: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +Creating a `PostData` object now can be done as such: + +```php +return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'image' => [ + 'filename' => 'images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png', + 'size' => 16524 + ], + 'published_at' => CarbonImmutable::create(2020, 05, 16), +]); +``` + +When we create the `PostData` object in a controller as such: + +```php +public function __invoke(PostData $postData) +{ + return $postData; +} +``` + +We get a validation error: + +```json +{ + "message": "The image must be an array. (and 2 more errors)", + "errors": { + "image": [ + "The image must be an array." + ], + "image.filename": [ + "The image.filename field is required." + ], + "image.size": [ + "The image.size field is required." + ] + } +} +``` + +This is a neat feature of data; it expects a nested `ImageData` data object when being created from the request, an array with the keys `filename` and `size`. + +We can completely skip validation for the `image` property by using the `WithoutValidation` attribute: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithoutValidation] + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +It is possible to override the validation rules generated by the package by defining a static `rules` method on the data object: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'status' => ['nullable', 'in:published'], + ]; + } +} +``` + +Please notice that it is impossible to override rules for nested data objects; those are always generated based on the nested data object's properties. + +## Usage in controllers + +We've been creating many data objects from all sorts of values, time to change course and go the other way around and start transforming data objects into arrays. + +Let's say we have an API controller that returns a post: + +```php +public function __invoke() +{ + return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'published_at' => CarbonImmutable::create(2020, 05, 16), + ]); +} +``` + +By returning a data object in a controller, it is automatically converted to JSON: + +```json +{ + "title": "Hello laravel-data", + "content": "This is an introduction post for the new package", + "status": "published", + "image": null, + "published_at": "2020-05-16T00:00:00+00:00" +} +``` + +You can also easily convert a data object into an array as such: + +```php +$postData->toArray(); +``` + +Which gives you an array like this: + +```php +array:5 [ + "title" => "Hello laravel-data" + "content" => "This is an introduction post for the new package" + "status" => "published" + "image" => null + "published_at" => "2020-05-16T00:00:00+00:00" +] +``` + +It is possible to transform a data object into an array and keep complex types like the `PostStatus` and `CarbonImmutable`: + +```php +$postData->all(); +``` + +This will give the following array: + +```php +array:5 [ + "title" => "Hello laravel-data" + "content" => "This is an introduction post for the new package" + "status" => App\Enums\PostStatus { + +name: "published" + +value: "published" + } + "image" => null + "published_at" => Carbon\CarbonImmutable { + ... + } +] + +``` + +As you can see, if we transform a data object to JSON, the `CarbonImmutable` published at date is transformed into a string. + +## Using transformers + +A few sections ago, we used casts to cast simple types into complex types. Transformers work the other way around. They transform complex types into simple ones and transform a data object into a simpler structure like an array or JSON. + +Like the `DateTimeInterfaceCast`, we also have a `DateTimeInterfaceTransformer` that converts `DateTime,` `Carbon,`... objects into strings. + +This `DateTimeInterfaceTransformer` is registered in the `data.php` config file and will automatically be used when a data object needs to transform a `DateTimeInterface` object: + +```php +'transformers' => [ + DateTimeInterface::class => \Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer::class, + \Illuminate\Contracts\Support\Arrayable::class => \Spatie\LaravelData\Transformers\ArrayableTransformer::class, +], +``` + +Remember the image object we created earlier; we stored a file size and filename in the object. But that could be more useful; let's provide the URL to the file when transforming the object. Just like casts, transformers also can be local. Let's implement one for `Image`: + +```php +class ImageTransformer implements Transformer +{ + public function transform(DataProperty $property, mixed $value, TransformationContext $context): string + { + if (! $value instanceof Image) { + throw new Exception("Not an image"); + } + + return url($value->filename); + } +} +``` + +We can now use this transformer in the data object like this: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + #[WithTransformer(ImageTransformer::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +In our controller, we return the object as such: + +```php +public function __invoke() +{ + return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'image' => [ + 'filename' => 'images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png', + 'size' => 16524 + ], + 'published_at' => CarbonImmutable::create(2020, 05, 16), + ]); +} +``` + +Which leads to the following JSON: + +```php +{ + "title": "Hello laravel-data", + "content": "This is an introduction post for the new package", + "status": "published", + "image": "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png", + "published_at": "2020-05-16T00:00:00+00:00" +} +``` + +You can read more about transformers [here](/docs/laravel-data/v4/as-a-resource/transformers). + +## Generating a blueprint + +We can now send our posts as JSON to the front, but what if we want to create a new post? When using Inertia, for example, we might need an empty blueprint object like this that the user could fill in: + +```json +{ + "title" : null, + "content" : null, + "status" : null, + "image": null, + "published_at" : null +} +``` + +Such an array can be generated with the `empty` method, which will return an empty array following the structure of your data object: + +```php +PostData::empty(); +``` + +Which will return the following array: + +```php +[ + 'title' => null, + 'content' => null, + 'status' => null, + 'image' => null, + 'published_at' => null, +] +``` + +It is possible to set the status of the post to draft by default: + +```php +PostData::empty([ + 'status' => PostStatus::draft; +]); +``` + +## Lazy properties + +For the last section of this quickstart, we will look at the `AuthorData` object again; let's say that we want to compose a list of all the authors. What if we had 100+ authors who have all written more than 100+ posts: + +```json +[ + { + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "image" : "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png", + "published_at" : "2021-09-24T13:31:20+00:00" + } + + // ... + ] + }, + { + "name" : "Freek van der Herten", + "posts" : [ + { + "title" : "Hello laravel-event-sourcing", + "content" : "This is an introduction post for the new package", + "status" : "published", + "image" : "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png" + "published_at" : "2021-09-24T13:31:20+00:00" + } + + // ... + ] + } + + // ... +] +``` + +As you can see, this will quickly be a large set of data we would send over JSON, which we don't want to do. Since each author includes his name and all the posts, he has written. + +In the end, we only want something like this: + +```json +[ + { + "name" : "Ruben Van Assche" + }, + { + "name" : "Freek van der Herten" + } + + // ... +] +``` + +This functionality can be achieved with lazy properties. Lazy properties are only added to a payload when we explicitly ask it. They work with closures that are executed only when this is required: + +```php +class AuthorData extends Data +{ + /** + * @param Collection|Lazy $posts + */ + public function __construct( + public string $name, + public Collection|Lazy $posts + ) { + } + + public static function fromModel(Author $author) + { + return new self( + $author->name, + Lazy::create(fn() => PostData::collect($author->posts)) + ); + } +} +``` + +When we now create a new author: + +```php +$author = Author::create([ + 'name' => 'Ruben Van Assche' +]); + +$author->posts()->create([ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => 'draft', + 'published_at' => null, + ] +]); + +AuthorData::from($author); +``` + +Transforming it into JSON looks like this: + +```json +{ + "name" : "Ruben Van Assche" +} +``` + +If we want to include the posts, the only thing we need to do is this: + +```php +$postData->include('posts')->toJson(); +``` + +Which will result in this JSON: + +```json +{ + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "published_at" : "2021-09-24T13:31:20+00:00" + } + ] +} +``` + +Let's take this one step further. What if we want to only include the title of each post? We can do this by making all the other properties within the post data object also lazy: + +```php +class PostData extends Data +{ + public function __construct( + public string|Lazy $title, + public string|Lazy $content, + public PostStatus|Lazy $status, + #[WithoutValidation] + #[WithCast(ImageCast::class)] + #[WithTransformer(ImageTransformer::class)] + public ImageData|Lazy|null $image, + #[Date] + public CarbonImmutable|Lazy|null $published_at + ) { + } + + public static function fromModel(Post $post): PostData + { + return new self( + Lazy::create(fn() => $post->title), + Lazy::create(fn() => $post->content), + Lazy::create(fn() => $post->status), + Lazy::create(fn() => $post->image), + Lazy::create(fn() => $post->published_at) + ); + } + + public static function rules(ValidationContext $context): array + { + return [ + 'image' => ['nullable', 'image'], + ]; + } +} +``` + +Now the only thing we need to do is include the title: + +```php +$postData->include('posts.title')->toJson(); +``` + +Which will result in this JSON: + +```json +{ + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data" + } + ] +} +``` + +If we also want to include the status, we can do the following: + +```php +$postData->include('posts.{title,status}')->toJson(); +``` + +It is also possible to include all properties of the posts like this: + +```php +$postData->include('posts.*')->toJson(); +``` + +You can do quite a lot with lazy properties like including them: + +- when a model relation is loaded like Laravel API resources +- when they are requested in the URL query +- by default, with an option to exclude them + +And a lot more. You can read all about it [here](/docs/laravel-data/v4/as-a-resource/lazy-properties). + +## Conclusion + +So that's it, a quick overview of this package. We barely scratched the surface of what's possible with the package. There's still a lot more you can do with data objects like: + +- [casting](/docs/laravel-data/v4/advanced-usage/eloquent-casting) them into Eloquent models +- [transforming](/docs/laravel-data/v4/advanced-usage/typescript) the structure to typescript +- [working](/docs/laravel-data/v4/as-a-data-transfer-object/collections) with `DataCollections` +- [optional properties](/docs/laravel-data/v4/as-a-data-transfer-object/optional-properties) not always required when creating a data object +- [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping) transformed data into keys +- [mapping](/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names) property names when creating or transforming a data object +- [appending](/docs/laravel-data/v4/as-a-resource/appending-properties) extra data +- [including](/docs/laravel-data/v4/as-a-resource/lazy-properties#content-using-query-strings) properties using the URL query string +- [inertia](https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-inertia) support for lazy properties +- and so much more ... you'll find all the information here in the docs diff --git a/_docs/laravel-libs/laravel-data/installation-setup.md b/_docs/laravel-libs/laravel-data/installation-setup.md new file mode 100644 index 0000000..b87d7a4 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/installation-setup.md @@ -0,0 +1,219 @@ +--- +title: Installation & setup +weight: 4 +--- + +You can install the package via composer: + +```bash +composer require spatie/laravel-data +``` + +Optionally, You can publish the config file with: + +```bash +php artisan vendor:publish --provider="Spatie\LaravelData\LaravelDataServiceProvider" --tag="data-config" +``` + +This is the contents of the published config file: + +```php + + DATE_ATOM, + + /* + * When transforming or casting dates, the following timezone will be used to + * convert the date to the correct timezone. If set to null no timezone will + * be passed. + */ + 'date_timezone' => null, + + /* + * It is possible to enable certain features of the package, these would otherwise + * be breaking changes, and thus they are disabled by default. In the next major + * version of the package, these features will be enabled by default. + */ + 'features' => [ + 'cast_and_transform_iterables' => false, + + /* + * When trying to set a computed property value, the package will throw an exception. + * You can disable this behaviour by setting this option to true, which will then just + * ignore the value being passed into the computed property and recalculate it. + */ + 'ignore_exception_when_trying_to_set_computed_property_value' => false, + ], + + /* + * Global transformers will take complex types and transform them into simple + * types. + */ + 'transformers' => [ + DateTimeInterface::class => \Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer::class, + \Illuminate\Contracts\Support\Arrayable::class => \Spatie\LaravelData\Transformers\ArrayableTransformer::class, + BackedEnum::class => Spatie\LaravelData\Transformers\EnumTransformer::class, + ], + + /* + * Global casts will cast values into complex types when creating a data + * object from simple types. + */ + 'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, + BackedEnum::class => Spatie\LaravelData\Casts\EnumCast::class, +// Enumerable::class => Spatie\LaravelData\Casts\EnumerableCast::class, + ], + + /* + * Rule inferrers can be configured here. They will automatically add + * validation rules to properties of a data object based upon + * the type of the property. + */ + 'rule_inferrers' => [ + Spatie\LaravelData\RuleInferrers\SometimesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\NullableRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\RequiredRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\BuiltInTypesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\AttributesRuleInferrer::class, + ], + + /* + * Normalizers return an array representation of the payload, or null if + * it cannot normalize the payload. The normalizers below are used for + * every data object, unless overridden in a specific data object class. + */ + 'normalizers' => [ + Spatie\LaravelData\Normalizers\ModelNormalizer::class, + // Spatie\LaravelData\Normalizers\FormRequestNormalizer::class, + Spatie\LaravelData\Normalizers\ArrayableNormalizer::class, + Spatie\LaravelData\Normalizers\ObjectNormalizer::class, + Spatie\LaravelData\Normalizers\ArrayNormalizer::class, + Spatie\LaravelData\Normalizers\JsonNormalizer::class, + ], + + /* + * Data objects can be wrapped into a key like 'data' when used as a resource, + * this key can be set globally here for all data objects. You can pass in + * `null` if you want to disable wrapping. + */ + 'wrap' => null, + + /* + * Adds a specific caster to the Symphony VarDumper component which hides + * some properties from data objects and collections when being dumped + * by `dump` or `dd`. Can be 'enabled', 'disabled' or 'development' + * which will only enable the caster locally. + */ + 'var_dumper_caster_mode' => 'development', + + /* + * It is possible to skip the PHP reflection analysis of data objects + * when running in production. This will speed up the package. You + * can configure where data objects are stored and which cache + * store should be used. + * + * Structures are cached forever as they'll become stale when your + * application is deployed with changes. You can set a duration + * in seconds if you want the cache to clear after a certain + * timeframe. + */ + 'structure_caching' => [ + 'enabled' => true, + 'directories' => [app_path('Data')], + 'cache' => [ + 'store' => env('CACHE_STORE', env('CACHE_DRIVER', 'file')), + 'prefix' => 'laravel-data', + 'duration' => null, + ], + 'reflection_discovery' => [ + 'enabled' => true, + 'base_path' => base_path(), + 'root_namespace' => null, + ], + ], + + /* + * A data object can be validated when created using a factory or when calling the from + * method. By default, only when a request is passed the data is being validated. This + * behaviour can be changed to always validate or to completely disable validation. + */ + 'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::OnlyRequests->value, + + /* + * A data object can map the names of its properties when transforming (output) or when + * creating (input). By default, the package will not map any names. You can set a + * global strategy here, or override it on a specific data object. + */ + 'name_mapping_strategy' => [ + 'input' => null, + 'output' => null, + ], + + /* + * When using an invalid include, exclude, only or except partial, the package will + * throw an exception. You can disable this behaviour by setting this option to true. + */ + 'ignore_invalid_partials' => false, + + /* + * When transforming a nested chain of data objects, the package can end up in an infinite + * loop when including a recursive relationship. The max transformation depth can be + * set as a safety measure to prevent this from happening. When set to null, the + * package will not enforce a maximum depth. + */ + 'max_transformation_depth' => null, + + /* + * When the maximum transformation depth is reached, the package will throw an exception. + * You can disable this behaviour by setting this option to true which will return an + * empty array. + */ + 'throw_when_max_transformation_depth_reached' => true, + + /* + * When using the `make:data` command, the package will use these settings to generate + * the data classes. You can override these settings by passing options to the command. + */ + 'commands' => [ + + /* + * Provides default configuration for the `make:data` command. These settings can be overridden with options + * passed directly to the `make:data` command for generating single Data classes, or if not set they will + * automatically fall back to these defaults. See `php artisan make:data --help` for more information + */ + 'make' => [ + + /* + * The default namespace for generated Data classes. This exists under the application's root namespace, + * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the + * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. + */ + 'namespace' => 'Data', + + /* + * This suffix will be appended to all data classes generated by make:data, so that they are less likely + * to conflict with other related classes, controllers or models with a similar name without resorting + * to adding an alias for the Data object. Set to a blank string (not null) to disable. + */ + 'suffix' => 'Data', + ], + ], + + /* + * When using Livewire, the package allows you to enable or disable the synths + * these synths will automatically handle the data objects and their + * properties when used in a Livewire component. + */ + 'livewire' => [ + 'enable_synths' => false, + ], +]; +``` diff --git a/_docs/laravel-libs/laravel-data/introduction.md b/_docs/laravel-libs/laravel-data/introduction.md new file mode 100644 index 0000000..3e9bd7c --- /dev/null +++ b/_docs/laravel-libs/laravel-data/introduction.md @@ -0,0 +1,58 @@ +--- +title: Introduction +weight: 1 +--- + +This package enables the creation of rich data objects which can be used in various ways. Using this package you only need to describe your data once: + +- instead of a form request, you can use a data object +- instead of an API transformer, you can use a data object +- instead of manually writing a typescript definition, you can use... 🥁 a data object + +A `laravel-data` specific object is just a regular PHP object that extends from `Data`: + +```php +use Spatie\LaravelData\Data; + +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +By extending from `Data` you enable a lot of new functionality like: + +- Automatically transforming data objects into resources (like the Laravel API resources) +- Transform only the requested parts of data objects with lazy properties +- Automatically creating data objects from request data and validating them +- Automatically resolve validation rules for properties within a data object +- Make it possible to construct a data object from any type you want +- Add support for automatically validating data objects when creating them +- Generate TypeScript definitions from your data objects you can use on the frontend +- Save data objects as properties of an Eloquent model +- And a lot more ... + +Why would you be using this package? + +- You can be sure that data is typed when it leaves your app and comes back again from the frontend which makes a lot less errors +- You don't have to write the same properties three times (in a resource, in a data transfer object and in request validation) +- You need to write a lot less of validation rules because they are obvious through PHP's type system +- You get TypeScript versions of the data objects for free + +Let's dive right into it! + +## Are you a visual learner? + +In this talk, given at Laracon US, you'll see [an introduction to Laravel Data](https://www.youtube.com/watch?v=CrO_7Df1cBc). + +## We have badges! + +
+ Latest Version + Software License + Total Downloads +
diff --git a/_docs/laravel-libs/laravel-data/questions-issues.md b/_docs/laravel-libs/laravel-data/questions-issues.md new file mode 100644 index 0000000..1c76ae3 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/questions-issues.md @@ -0,0 +1,8 @@ +--- +title: Questions and issues +weight: 6 +--- + +Find yourself stuck using the package? Found a bug? Do you have general questions or suggestions for improving Laravel Data? Feel free to [create an issue on GitHub](https://github.com/spatie/laravel-data/issues), we'll try to address it as soon as possible. + +If you've found a bug regarding security please mail [freek@spatie.be](mailto:freek@spatie.be) instead of using the issue tracker. diff --git a/_docs/laravel-libs/laravel-data/requirements.md b/_docs/laravel-libs/laravel-data/requirements.md new file mode 100644 index 0000000..ab37db0 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/requirements.md @@ -0,0 +1,8 @@ +--- +title: Requirements +weight: 3 +--- + +This package requires: +- PHP 8.1 or higher +- Laravel 10 or higher diff --git a/_docs/laravel-libs/laravel-data/support-us.md b/_docs/laravel-libs/laravel-data/support-us.md new file mode 100644 index 0000000..0453692 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/support-us.md @@ -0,0 +1,8 @@ +--- +title: Support us +weight: 2 +--- + +We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). + +We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). diff --git a/_docs/laravel-libs/laravel-data/third-party-packages.md b/_docs/laravel-libs/laravel-data/third-party-packages.md new file mode 100644 index 0000000..7efa4dc --- /dev/null +++ b/_docs/laravel-libs/laravel-data/third-party-packages.md @@ -0,0 +1,12 @@ +--- +title: Third party packages +weight: 5 +--- + +Some community members created packages that extend the functionality of Laravel Data. Here's a list of them: + +- [laravel-typescript-transformer](https://github.com/spatie/laravel-typescript-transformer) +- [laravel-data-openapi-generator](https://github.com/xolvionl/laravel-data-openapi-generator) +- [laravel-data-json-schemas](https://github.com/BasilLangevin/laravel-data-json-schemas) + +Created a package yourself that you want to add to this list? Send us a PR! diff --git a/_docs/laravel-libs/laravel-data/validation/_index.md b/_docs/laravel-libs/laravel-data/validation/_index.md new file mode 100644 index 0000000..77dfeed --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/_index.md @@ -0,0 +1,4 @@ +--- +title: Validation +weight: 3 +--- diff --git a/_docs/laravel-libs/laravel-data/validation/auto-rule-inferring.md b/_docs/laravel-libs/laravel-data/validation/auto-rule-inferring.md new file mode 100644 index 0000000..50cadef --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/auto-rule-inferring.md @@ -0,0 +1,60 @@ +--- +title: Auto rule inferring +weight: 2 +--- + +The package will automatically infer validation rules from the data object. For example, for the following data class: + +```php +class ArtistData extends Data{ + public function __construct( + public string $name, + public int $age, + public ?string $genre, + ) { + } +} +``` + +The package will generate the following validation rules: + +```php +[ + 'name' => ['required', 'string'], + 'age' => ['required', 'integer'], + 'genre' => ['nullable', 'string'], +] +``` + +All these rules are inferred by `RuleInferrers`, special classes that will look at the types of properties and will add rules based upon that. + +Rule inferrers are configured in the `data.php` config file: + +```php +/* + * Rule inferrers can be configured here. They will automatically add + * validation rules to properties of a data object based upon + * the type of the property. + */ +'rule_inferrers' => [ + Spatie\LaravelData\RuleInferrers\SometimesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\NullableRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\RequiredRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\BuiltInTypesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\AttributesRuleInferrer::class, +], +``` + +By default, five rule inferrers are enabled: + +- **SometimesRuleInferrer** will add a `sometimes` rule when the property is optional +- **NullableRuleInferrer** will add a `nullable` rule when the property is nullable +- **RequiredRuleInferrer** will add a `required` rule when the property is not nullable +- **BuiltInTypesRuleInferrer** will add a rules which are based upon the built-in php types: + - An `int` or `float` type will add the `numeric` rule + - A `bool` type will add the `boolean` rule + - A `string` type will add the `string` rule + - A `array` type will add the `array` rule +- **AttributesRuleInferrer** will make sure that rule attributes we described above will also add their rules + +It is possible to write your rule inferrers. You can find more information [here](/docs/laravel-data/v4/advanced-usage/creating-a-rule-inferrer). diff --git a/_docs/laravel-libs/laravel-data/validation/introduction.md b/_docs/laravel-libs/laravel-data/validation/introduction.md new file mode 100644 index 0000000..df02f56 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/introduction.md @@ -0,0 +1,325 @@ +--- +title: Introduction +weight: 1 +--- + +Laravel data, allows you to create data objects from all sorts of data. One of the most common ways to create a data object is from a request, and the data from a request cannot always be trusted. + +That's why it is possible to validate the data before creating the data object. You can validate requests but also arrays and other structures. + +The package will try to automatically infer validation rules from the data object, so you don't have to write them yourself. For example, a `?string` property will automatically have the `nullable` and `string` rules. + +### Important notice + +Validation is probably one of the coolest features of this package, but it is also the most complex one. We'll try to make it as straightforward as possible to validate data, but in the end, the Laravel validator was not written to be used in this way. So there are some limitations and quirks you should be aware of. + +In a few cases it might be easier to just create a custom request class with validation rules and then call `toArray` on the request to create a data object than trying to validate the data with this package. + +## When does validation happen? + +Validation will always happen BEFORE a data object is created, once a data object is created, it is assumed that the data is valid. + +At the moment, there isn't a way to validate data objects, so you should implement this logic yourself. We're looking into ways to make this easier in the future. + +Validation runs automatically in the following cases: + +- When injecting a data object somewhere and the data object gets created from the request +- When calling the `from` method on a data object with a request + +On all other occasions, validation won't run automatically. You can always validate the data manually by calling the `validate` method on a data object: + +```php +SongData::validate( + ['title' => 'Never gonna give you up'] +); // ValidationException will be thrown because 'artist' is missing +``` + +When you also want to create the object after validation was successful you can use `validateAndCreate`: + +```php +SongData::validateAndCreate( + ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley'] +); // returns a SongData object +``` + +### Validate everything + +It is possible to validate all payloads injected or passed to the `from` method by setting the `validation_strategy` config option to `Always`: + +```php +'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::Always->value, +``` + +Completely disabling validation can be done by setting the `validation_strategy` config option to `Disabled`: + +```php +'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::Disabled->value, +``` + +If you require a more fine-grained control over when validation should happen, you can use [data factories](/docs/laravel-data/v4/as-a-data-transfer-object/factories) to manually specify the validation strategy. + +## A quick glance at the validation functionality + +We've got a lot of documentation about validation and we suggest you read it all, but if you want to get a quick glance at the validation functionality, here's a quick overview: + +### Auto rule inferring + +The package will automatically infer validation rules from the data object. For example, for the following data class: + +```php +class ArtistData extends Data{ + public function __construct( + public string $name, + public int $age, + public ?string $genre, + ) { + } +} +``` + +The package will generate the following validation rules: + +```php +[ + 'name' => ['required', 'string'], + 'age' => ['required', 'integer'], + 'genre' => ['nullable', 'string'], +] +``` + +The package follows an algorithm to infer rules from the data object. You can read more about it [here](/docs/laravel-data/v4/validation/auto-rule-inferring). + +### Validation attributes + +It is possible to add extra rules as attributes to properties of a data object: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(20)] + public string $artist, + ) { + } +} +``` + +When you provide an artist with a length of more than 20 characters, the validation will fail. + +There's a complete [chapter](/docs/laravel-data/v4/validation/using-validation-attributes) dedicated to validation attributes. + +### Manual rules + +Sometimes you want to add rules manually, this can be done as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['required', 'string'], + 'artist' => ['required', 'string'], + ]; + } +} +``` + +You can read more about manual rules in its [dedicated chapter](/docs/laravel-data/v4/validation/manual-rules). + +### Using the container + +You can resolve a data object from the container. + +```php +app(SongData::class); +``` + +We resolve a data object from the container, its properties will already be filled by the values of the request with matching key names. +If the request contains data that is not compatible with the data object, a validation exception will be thrown. + +### Working with the validator + +We provide a few points where you can hook into the validation process. You can read more about it in the [dedicated chapter](/docs/laravel-data/v4/validation/working-with-the-validator). + +It is for example to: + +- overwrite validation messages & attributes +- overwrite the validator itself +- overwrite the redirect when validation fails +- allow stopping validation after a failure +- overwrite the error bag + +### Authorizing a request + +Just like with Laravel requests, it is possible to authorize an action for certain people only: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function authorize(): bool + { + return Auth::user()->name === 'Ruben'; + } +} +``` + +If the method returns `false`, then an `AuthorizationException` is thrown. + +## Validation of nested data objects + +When a data object is nested inside another data object, the validation rules will also be generated for that nested object. + +```php +class SingleData{ + public function __construct( + public ArtistData $artist, + public SongData $song, + ) { + } +} +``` + +The validation rules for this class will be: + +```php +[ + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], + 'artist.genre' => ['nullable', 'string'], + 'song' => ['array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['required', 'string'], +] +``` + +There are a few quirky things to keep in mind when working with nested data objects, you can read all about it [here](/docs/laravel-data/v4/validation/nesting-data). + +## Validation of nested data collections + +Let's say we want to create a data object like this from a request: + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +Since the `SongData` has its own validation rules, the package will automatically apply them when resolving validation +rules for this object. + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` + +More info about nested data collections can be found [here](/docs/laravel-data/v4/validation/nesting-data). + +## Default values + +When you've set some default values for a data object, the validation rules will only be generated if something else than the default is provided. + +For example, when we have this data object: + +```php +class SongData extends Data +{ + public function __construct( + public string $title = 'Never Gonna Give You Up', + public string $artist = 'Rick Astley', + ) { + } +} +``` + +And we try to validate the following data: + +```php +SongData::validate( + ['title' => 'Giving Up On Love'] +); +``` + +Then the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], +] +``` + +## Mapping property names + +When mapping property names, the validation rules will be generated for the mapped property name: + +```php +class SongData extends Data +{ + public function __construct( + #[MapInputName('song_title')] + public string $title, + ) { + } +} +``` + +The validation rules for this class will be: + +```php +[ + 'song_title' => ['required', 'string'], +] +``` + +There's one small catch when the validation fails; the error message will be for the original property name, not the mapped property name. This is a small quirk we hope to solve as soon as possible. + +## Retrieving validation rules for a data object + +You can retrieve the validation rules a data object will generate as such: + +```php +AlbumData::getValidationRules($payload); +``` + +This will produce the following array with rules: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` + +### Payload requirement + +We suggest always providing a payload when generating validation rules. Because such a payload is used to determine which rules will be generated and which can be skipped. diff --git a/_docs/laravel-libs/laravel-data/validation/manual-rules.md b/_docs/laravel-libs/laravel-data/validation/manual-rules.md new file mode 100644 index 0000000..beb6554 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/manual-rules.md @@ -0,0 +1,223 @@ +--- +title: Manual rules +weight: 4 +--- + +It is also possible to write rules down manually in a dedicated method on the data object. This can come in handy when you want +to construct a custom rule object which isn't possible with attributes: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['required', 'string'], + 'artist' => ['required', 'string'], + ]; + } +} +``` + +By overwriting a property's rules within the `rules` method, no other rules will be inferred automatically anymore for that property. + +This means that in the following example, only a `max:20` rule will be added, and not a `string` and `required` rule: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['max:20'], + 'artist' => ['max:20'], + ]; + } +} + +// The generated rules will look like this +[ + 'title' => ['max:20'], + 'artist' => ['max:20'], +] +``` + +As a rule of thumb always follow these rules: + +Always use the array syntax for defining rules and not a single string which spits the rules by | characters. +This is needed when using regexes those | can be seen as part of the regex + +## Merging manual rules + +Writing manual rules doesn't mean that you can't use the automatic rules inferring anymore. By adding the `MergeValidationRules` attribute to your data class, the rules will be merged: + +```php +#[MergeValidationRules] +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['max:20'], + 'artist' => ['max:20'], + ]; + } +} + +// The generated rules will look like this +[ + 'title' => [required, 'string', 'max:20'], + 'artist' => [required, 'string', 'max:20'], +] +``` + +## Using attributes + +It is even possible to use the validationAttribute objects within the `rules` method: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => [new Required(), new StringType()], + 'artist' => [new Required(), new StringType()], + ]; + } +} +``` + + +You can even add dependencies to be automatically injected: + +```php +use SongSettingsRepository; + +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(SongSettingsRepository $settings): array + { + return [ + 'title' => [new RequiredIf($settings->forUser(auth()->user())->title_required), new StringType()], + 'artist' => [new Required(), new StringType()], + ]; + } +} +``` + +## Using context + +Sometimes a bit more context is required, in such a case a `ValidationContext` parameter can be injected as such: +Additionally, if you need to access the data payload, you can use `$payload` parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'title' => ['required'], + 'artist' => Rule::requiredIf($context->fullPayload['title'] !== 'Never Gonna Give You Up'), + ]; + } +} +``` + +By default, the provided payload is the whole request payload provided to the data object. +If you want to generate rules in nested data objects, then a relative payload can be more useful: + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} + +class SongData extends Data +{ + public function __construct( + public string $title, + public ?string $artist, + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'title' => ['required'], + 'artist' => Rule::requiredIf($context->payload['title'] !== 'Never Gonna Give You Up'), + ]; + } +} +``` + +When providing such a payload: + +```php +[ + 'title' => 'Best songs ever made', + 'songs' => [ + ['title' => 'Never Gonna Give You Up'], + ['title' => 'Heroes', 'artist' => 'David Bowie'], + ], +]; +``` + +The rules will be: + +```php +[ + 'title' => ['string', 'required'], + 'songs' => ['present', 'array'], + 'songs.*.title' => ['string', 'required'], + 'songs.*.artist' => ['string', 'nullable'], + 'songs.*' => [NestedRules(...)], +] +``` + +It is also possible to retrieve the current path in the data object chain we're generating rules for right now by calling `$context->path`. In the case of our previous example this would be `songs.0` and `songs.1`; + +Make sure the name of the parameter is `$context` in the `rules` method, otherwise no context will be injected. diff --git a/_docs/laravel-libs/laravel-data/validation/nesting-data.md b/_docs/laravel-libs/laravel-data/validation/nesting-data.md new file mode 100644 index 0000000..f8402fa --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/nesting-data.md @@ -0,0 +1,129 @@ +--- +title: Nesting Data +weight: 6 +--- + +A data object can contain other data objects or collections of data objects. The package will make sure that also for these data objects validation rules will be generated. + +Let's take a look again at the data object from the [nesting](/docs/laravel-data/v4/as-a-data-transfer-object/nesting) section: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ArtistData $artist, + ) { + } +} +``` + +The validation rules for this class would be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +## Validating a nested collection of data objects + +When validating a data object like this + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['present', 'array', new NestedRules()], +] +``` + +The `NestedRules` class is a Laravel validation rule that will validate each item within the collection for the rules defined on the data class for that collection. + +## Nullable and Optional nested data + +If we make the nested data object nullable, the validation rules will change depending on the payload provided: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ?ArtistData $artist, + ) { + } +} +``` + +If no value for the nested object key was provided or the value is `null`, the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['nullable'], +] +``` + +If, however, a value was provided (even an empty array), the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +The same happens when a property is made optional: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ArtistData $artist, + ) { + } +} +``` + +There's a small difference compared against nullable, though. When no value was provided for the nested object key, the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['present', 'array', new NestedRules()], +] +``` + +However, when a value was provided (even an empty array or null), the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +We've written a [blog post](https://flareapp.io/blog/fixing-nested-validation-in-laravel) on the reasoning behind these variable validation rules based upon payload. And they are also the reason why calling `getValidationRules` on a data object always requires a payload to be provided. diff --git a/_docs/laravel-libs/laravel-data/validation/skipping-validation.md b/_docs/laravel-libs/laravel-data/validation/skipping-validation.md new file mode 100644 index 0000000..f5c9695 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/skipping-validation.md @@ -0,0 +1,66 @@ +--- +title: Skipping validation +weight: 7 +--- + +Sometimes you don't want properties to be automatically validated, for instance when you're manually overwriting the +rules method like this: + +```php +class SongData extends Data +{ + public function __construct( + public string $name, + ) { + } + + public static function fromRequest(Request $request): static{ + return new self("{$request->input('first_name')} {$request->input('last_name')}") + } + + public static function rules(): array + { + return [ + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], + ]; + } +} +``` + +When a request is being validated, the rules will look like this: + +```php +[ + 'name' => ['required', 'string'], + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], +] +``` + +We know we never want to validate the `name` property since it won't be in the request payload, this can be done as +such: + +```php +class SongData extends Data +{ + public function __construct( + #[WithoutValidation] + public string $name, + ) { + } +} +``` + +Now the validation rules will look like this: + +```php +[ + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], +] +``` + +## Skipping validation for all properties + +By using [data factories](/docs/laravel-data/v4/as-a-data-transfer-object/factories) or setting the `validation_strategy` in the `data.php` config you can skip validation for all properties of a data class. diff --git a/_docs/laravel-libs/laravel-data/validation/using-validation-attributes.md b/_docs/laravel-libs/laravel-data/validation/using-validation-attributes.md new file mode 100644 index 0000000..1cfc035 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/using-validation-attributes.md @@ -0,0 +1,264 @@ +--- +title: Using validation attributes +weight: 3 +--- + +It is possible to add extra rules as attributes to properties of a data object: + +```php +class SongData extends Data +{ + public function __construct( + #[Uuid()] + public string $uuid, + #[Max(15), IP, StartsWith('192.')] + public string $ip, + ) { + } +} +``` + +These rules will be merged together with the rules that are inferred from the data object. + +So it is not required to add the `required` and `string` rule, these will be added automatically. The rules for the +above data object will look like this: + +```php +[ + 'uuid' => ['required', 'string', 'uuid'], + 'ip' => ['required', 'string', 'max:15', 'ip', 'starts_with:192.'], +] +``` + +For each Laravel validation rule we've got a matching validation attribute, you can find a list of +them [here](/docs/laravel-data/v4/advanced-usage/validation-attributes). + +## Referencing route parameters + +Sometimes you need a value within your validation attribute which is a route parameter. +Like the example below where the id should be unique ignoring the current id: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Unique('songs', ignore: new RouteParameterReference('song'))] + public int $id, + ) { + } +} +``` + +If the parameter is a model and another property should be used, then you can do the following: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Unique('songs', ignore: new RouteParameterReference('song', 'uuid'))] + public string $uuid, + ) { + } +} +``` + +## Referencing the current authenticated user + +If you need to reference the current authenticated user in your validation attributes, you can use the +`AuthenticatedUserReference`: + +```php +use Spatie\LaravelData\Support\Validation\References\AuthenticatedUserReference; + +class UserData extends Data +{ + public function __construct( + public string $name, + #[Unique('users', 'email', ignore: new AuthenticatedUserReference())] + public string $email, + ) { + } +} +``` + +When you need to reference a specific property of the authenticated user, you can do so like this: + +```php +class SongData extends Data +{ + public function __construct( + #[Max(new AuthenticatedUserReference('max_song_title_length'))] + public string $title, + ) { + } +} +``` + +Using a different guard than the default one can be done by passing the guard name to the constructor: + +```php +class UserData extends Data +{ + public function __construct( + public string $name, + #[Unique('users', 'email', ignore: new AuthenticatedUserReference(guard: 'api'))] + public string $email, + ) { + } +} +``` + +## Referencing container dependencies + +If you need to reference a container dependency in your validation attributes, you can use the `ContainerReference`: + +```php +use Spatie\LaravelData\Support\Validation\References\ContainerReference; + +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference('max_song_title_length'))] + public string $artist, + ) { + } +} +``` + +It might be more useful to use a property of the container dependency, which can be done like this: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length'))] + public string $artist, + ) { + } +} +``` + +When your dependency requires specific parameters, you can pass them along: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length', parameters: ['repository' => 'redis']))] + public string $artist, + ) { + } +} +``` + + +## Referencing other fields + +It is possible to reference other fields in validation attributes: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[RequiredIf('title', 'Never Gonna Give You Up')] + public string $artist, + ) { + } +} +``` + +These references are always relative to the current data object. So when being nested like this: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $album_name, + public SongData $song, + ) { + } +} +``` + +The generated rules will look like this: + +```php +[ + 'album_name' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['string', 'required_if:song.title,"Never Gonna Give You Up"'], +] +``` + +If you want to reference fields starting from the root data object you can do the following: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[RequiredIf(new FieldReference('album_name', fromRoot: true), 'Whenever You Need Somebody')] + public string $artist, + ) { + } +} +``` + +The rules will now look like this: + +```php +[ + 'album_name' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['string', 'required_if:album_name,"Whenever You Need Somebody"'], +] +``` + +## Rule attribute + +One special attribute is the `Rule` attribute. With it, you can write rules just like you would when creating a custom +Laravel request: + +```php +// using an array +#[Rule(['required', 'string'])] +public string $property + +// using a string +#[Rule('required|string')] +public string $property + +// using multiple arguments +#[Rule('required', 'string')] +public string $property +``` + +## Creating your validation attribute + +It is possible to create your own validation attribute by extending the `CustomValidationAttribute` class, this class +has a `getRules` method that returns the rules that should be applied to the property. + +```php +#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)] +class CustomRule extends CustomValidationAttribute +{ + /** + * @return array|object|string + */ + public function getRules(ValidationPath $path): array|object|string + { + return [new CustomRule()]; + } +} +``` + +Quick note: you can only use these rules as an attribute, not as a class rule within the static `rules` method of the +data class. diff --git a/_docs/laravel-libs/laravel-data/validation/working-with-the-validator.md b/_docs/laravel-libs/laravel-data/validation/working-with-the-validator.md new file mode 100644 index 0000000..4df3798 --- /dev/null +++ b/_docs/laravel-libs/laravel-data/validation/working-with-the-validator.md @@ -0,0 +1,162 @@ +--- +title: Working with the validator +weight: 5 +--- + +Sometimes a more fine-grained control over the validation is required. In such case you can hook into the validator. + +## Overwriting messages + +It is possible to overwrite the error messages that will be returned when an error fails: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function messages(): array + { + return [ + 'title.required' => 'A title is required', + 'artist.required' => 'An artist is required', + ]; + } +} +``` + +## Overwriting attributes + +In the default Laravel validation rules, you can overwrite the name of the attribute as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function attributes(): array + { + return [ + 'title' => 'titel', + 'artist' => 'artiest', + ]; + } +} +``` + +## Overwriting other validation functionality + +Next to overwriting the validator, attributes and messages it is also possible to overwrite the following functionality. + +The redirect when a validation failed: + +```php +class SongData extends Data +{ + // ... + + public static function redirect(): string + { + return action(HomeController::class); + } +} +``` + +Or the route which will be used to redirect after a validation failed: + +```php +class SongData extends Data +{ + // ... + + public static function redirectRoute(): string + { + return 'home'; + } +} +``` + +Whether to stop validating on the first failure: + +```php +class SongData extends Data +{ + // ... + + public static function stopOnFirstFailure(): bool + { + return true; + } +} +``` + +The name of the error bag: + +```php +class SongData extends Data +{ + // ... + + public static function errorBag(): string + { + return 'never_gonna_give_an_error_up'; + } +} +``` + +### Using dependencies in overwritten functionality + +You can also provide dependencies to be injected in the overwritten validator functionality methods like `messages` +, `attributes`, `redirect`, `redirectRoute`, `stopOnFirstFailure`, `errorBag`: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function attributes( + ValidationAttributesLanguageRepository $validationAttributesLanguageRepository + ): array + { + return [ + 'title' => $validationAttributesLanguageRepository->get('title'), + 'artist' => $validationAttributesLanguageRepository->get('artist'), + ]; + } +} +``` + +## Overwriting the validator + +Before validating the values, it is possible to plugin into the validator. This can be done as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function withValidator(Validator $validator): void + { + $validator->after(function ($validator) { + $validator->errors()->add('field', 'Something is wrong with this field!'); + }); + } +} +``` + +Please note that this method will only be called on the root data object that is being validated, all the nested data objects and collections `withValidator` methods will not be called. diff --git a/_docs/laravel-libs/saloon-docs/README.md b/_docs/laravel-libs/saloon-docs/README.md new file mode 100644 index 0000000..a9909c8 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/README.md @@ -0,0 +1,23 @@ +--- +description: Build beautiful API integrations and SDKs with Saloon +--- + +# 🤠 Saloon + +Saloon is a PHP library that helps you rapidly build third party API integrations or SDKs. It's configured to be production-ready by default, offers a simple, standardised development flow for your whole team and has utilities to help test your API integrations before you ship to production. Saloon is loved by thousands of developers and downloaded over 2 million times. + +[![Build Status](https://github.com/saloonphp/saloon/actions/workflows/tests.yml/badge.svg)](https://img.shields.io/github/actions/workflow/status/saloonphp/saloon/tests.yml?label=tests)![](https://img.shields.io/packagist/dm/saloonphp/saloon)![](https://img.shields.io/github/stars/saloonphp/saloon) + +

Introducing Saloon v3

+ +### Key Features + +* Lightweight, only depends on one library - Guzzle. +* Offers "Connector" and "Request" classes to encapsulate API integrations into files +* Allows you to record real requests in your tests so you have accurate testing data for your assertions. +* Works in any PHP framework, or just regular PHP applications (with Composer) +* Comes with powerful plugins to handle caching, rate limits, data transfer objects, XML, and more + +{% content-ref url="the-basics/installation.md" %} +[installation.md](the-basics/installation.md) +{% endcontent-ref %} diff --git a/_docs/laravel-libs/saloon-docs/SUMMARY.md b/_docs/laravel-libs/saloon-docs/SUMMARY.md new file mode 100644 index 0000000..fb75760 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/SUMMARY.md @@ -0,0 +1,68 @@ +# Table of contents + +* [🤠 Saloon](README.md) + +## Upgrade + +* [🪄 What's new in v3](upgrade/whats-new-in-v3.md) +* [🌳 Upgrading from v2](upgrade/upgrading-from-v2.md) + +## The Basics + +* [⬇️ Installation](the-basics/installation.md) +* [🔌 Connectors](the-basics/connectors.md) +* [✉️ Requests](the-basics/requests.md) +* [🔐 Authentication](the-basics/authentication.md) +* [🎁 Sending Body/Data](the-basics/request-body-data/README.md) + * [JSON Body](the-basics/request-body-data/json-body.md) + * [Multipart Form Body](the-basics/request-body-data/multipart-form-body.md) + * [XML Body](the-basics/request-body-data/xml-body.md) + * [URL Encoded Body (Form)](the-basics/request-body-data/form-body-url-encoded.md) + * [String / Plain Text Body](the-basics/request-body-data/string-plain-text-body.md) + * [Stream Body](the-basics/request-body-data/stream-body.md) +* [🚀 Sending Requests](the-basics/sending-requests.md) +* [📡 Responses](the-basics/responses.md) +* [🔥 Handling Failures](the-basics/handling-failures.md) +* [🔎 Debugging](the-basics/debugging.md) +* [✅ Testing](the-basics/testing/README.md) + +## Digging Deeper + +* [🛸 Data Transfer Objects](the-basics/data-transfer-objects.md) +* [✨ Building SDKs](the-basics/building-sdks.md) +* [☝️ Solo Requests](digging-deeper/solo-requests.md) +* [🎯 Retrying Requests](digging-deeper/retrying-requests.md) +* [⏸️ Delaying Requests](digging-deeper/delay.md) +* [🏎️ Concurrency & Pools](digging-deeper/concurrency-and-pools.md) +* [🔑 OAuth2](digging-deeper/oauth2-authentication/README.md) + * [Authorization Code Grant](digging-deeper/oauth2-authentication/oauth2-authentication.md) + * [Client Credentials Grant](digging-deeper/oauth2-authentication/client-credentials-grant.md) +* [💫 Middleware](digging-deeper/middleware.md) +* [⛩️ PSR Support](digging-deeper/psr-support.md) + +## Installable Plugins + +* [📚 Pagination](digging-deeper/pagination/README.md) + * [Paged Pagination](digging-deeper/pagination/paged-pagination.md) + * [Limit/Offset Pagination](digging-deeper/pagination/limit-offset-pagination.md) + * [Cursor Pagination](digging-deeper/pagination/cursor-pagination.md) + * [Custom Pagination](digging-deeper/pagination/custom-pagination.md) +* [⛵ Laravel Plugin](installable-plugins/laravel-integration.md) +* [🔁 Caching](installable-plugins/caching-responses.md) +* [⛔ Rate Limit Handler](installable-plugins/handling-rate-limits.md) +* [🏭 Auto SDK Generator](installable-plugins/sdk-generator.md) +* [🤠 Lawman](installable-plugins/lawman.md) +* [🏇 XML Wrangler](installable-plugins/xml-wrangler.md) +* [🏗️ Building Your Own Plugins](installable-plugins/traits.md) + +## Conclusion + +* [📘 Official Book!](conclusion/official-book.md) +* [📔 How-to Guides](conclusion/how-to-guides/README.md) + * [Improving Speed With Laravel](conclusion/how-to-guides/improving-speed-with-laravel.md) + * [Per-request Authentication](conclusion/how-to-guides/per-request-authentication.md) +* [📖 Tutorials & Blog Posts](conclusion/tutorials.md) +* [🎖️ Showcase](conclusion/showcase.md) +* [💥 Known Issues](conclusion/known-issues.md) +* [🤗 Credits](conclusion/credits.md) +* [❤️ Support Saloon](https://github.com/sponsors/Sammyjo20) diff --git a/_docs/laravel-libs/saloon-docs/conclusion/credits.md b/_docs/laravel-libs/saloon-docs/conclusion/credits.md new file mode 100644 index 0000000..4b3db9f --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/credits.md @@ -0,0 +1,14 @@ +# 🤗 Credits + +### Special Thanks + +* [Juse Less](https://github.com/juse-less) for contributing to many core features of Saloon v2 but mainly pagination and debugging. +* [Tom Witkowski](https://github.com/Gummibeer) for contributing to Saloon's fixture recording and helping decide many core parts of version two like data transfer objects and the error handler. +* [Caneco](https://github.com/caneco) for such a wonderful logo and branding. +* [Ashley Allen](https://github.com/ash-jc-allen) for working closely with me and writing an amazing book that features Saloon ([Consuming APIs in Laravel](https://consuming-apis-in-laravel.com/)). Ashley made countless contributions to the documentation and helped make decisions for v3. + +### But also... Thank _you_. + +This is my chance to thank you - the amazing PHP community for installing, using and contributing to Saloon's success. I absolutely love working on open source and working within the PHP community as it feels so rewarding. It's an absolute honour to build something that people enjoy and actively use. I hope it will be useful for many years ahead.. + +[**Sam Carré**](https://github.com/sammyjo20) diff --git a/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/README.md b/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/README.md new file mode 100644 index 0000000..d12e504 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/README.md @@ -0,0 +1,8 @@ +--- +description: >- + This page contains a collection of useful start-to-finish guides for doing + specific things in Saloon. +--- + +# 📔 How-to Guides + diff --git a/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/improving-speed-with-laravel.md b/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/improving-speed-with-laravel.md new file mode 100644 index 0000000..502fdcd --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/how-to-guides/improving-speed-with-laravel.md @@ -0,0 +1,45 @@ +# Improving Speed With Laravel + +If you are using Laravel, then you are probably aware of its powerful container that keeps objects open in the background while you make requests or process jobs. Saloon uses Guzzle under the hood, which keeps connections open for as long as it can - which is why subsequent requests using the same connector is usually faster. Typically though, the Guzzle HTTP client will be destructed and connections closed between requests/jobs. This results in increased request times if you are doing lots of API calls across jobs or requests because it is establishing a new connection each time. + +If you are using Laravel, you can bind an instance of Saloon's `GuzzleSender` inside of its container and it will keep connections open between queued jobs and requests (if you are using Octane). This can provide a nice speed boost if you are using the same API service, especially if you are frequently accessing an API, like migrating data from an external API into your application. + +First, you should create a new singleton in one of your service provider's register methods, and return a new instance of `GuzzleSender`. The `AppServiceProvider` is a good place to put this, or you could create a new `HttpServiceProvider` for this. + +```php +app->singleton(GuzzleSender::class, fn () => new GuzzleSender); + } +} +``` + +Now, inside your Saloon connectors, you should overwrite the `defaultSender` method and resolve the sender which you have bound to the container. + +```php +send(new GetAccessTokenRequest(username: 'Sam', password: 'yee-haw')); +$token = $authResponse->json()['token']; + +$songsRequest = new GetSongsByArtistRequest('Luke Combs'); +$songsRequest->withTokenAuth($token); + +$response = $api->send($songsRequest); +``` + +This is pretty cumbersome. Every time you have to make a request, you have to write all these lines of code. One way you can get around this is by utilizing the `boot` method on your connector. Let's try refactoring this. + +In our connector, we'll extend the `boot()` method which is a method that runs before every request that is sent through that connector, and you get access to the special `PendingRequest` class which is a class that is used to store all the information of a request to be sent in a temporary way. We'll move our logic into here. + +```php +getRequest() instanceof GetAccessTokenRequest) { + return; + } + + // Now let's make our authentication request. Since we are in the + // context of the connector, we can just simply call $this and + // make another request! + + $authResponse = $this->send(new GetAccessTokenRequest($this->username, $this->password)); + + // Now we'll take the token from the auth response and then pass it + // into the $pendingRequest which is the original GetSongsByArtistRequest. + + $pendingRequest->authenticate(new TokenAuthenticator($authResponse->json()['token'])); + } +} +``` + +Now when we send any request using this connector, the authentication will be handled every time! We do have to make sure to pass in our authentication requirements (username, password) into the connector, but this is way better than repeating the same code. Saloon is all about standardisation! + +```php +send(new GetSongsByArtistRequest('Luke Combs')); + +// 200 body: [{name: 'When it rains, it pours'}] +``` + +You may also write additional logic inside of the boot method, like caching access tokens and reusing them. diff --git a/_docs/laravel-libs/saloon-docs/conclusion/known-issues.md b/_docs/laravel-libs/saloon-docs/conclusion/known-issues.md new file mode 100644 index 0000000..0f45579 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/known-issues.md @@ -0,0 +1,53 @@ +# 💥 Known Issues + +### Usage of anonymous functions with long-running processes like Laravel Queues + +There appears to be an issue with PHP which means any object that has an anonymous function inside of one of its properties will result in it not properly being destructed or running the `__destruct()` method. With Saloon, take care when using anonymous functions inside your connector or solo request because we have found that if you have an anonymous function/closure inside of the connector and when running it from within a long-running process like Laravel Queues, it won't close connections. + +This is because as mentioned above, the connector isn't able to be appropriately destructed which results in the sender and the sender's HTTP client like Guzzle not being able to be destructed and finally resulting in a "leak" of connections. This can cause further issues like the operating system running out of file handles and causing errors like "Too many files open". + +You can workaround this by changing the way you define your anonymous closure. You can: + +* Move the logic into an invokable class +* Make the closure _static_ + +```php +middleware()->onRequest(function () { + // + }); + + // ✅ Using an invokable class will work + $this->middleware()->onRequest(new MyRequestMiddleware); + + // ✅ Using static will work + $this->middleware()->onRequest(static function () { + // + }); + } +} +``` + +### Minimum TLS Version + +From version three, Saloon uses Guzzle `^7.6` which introduced a new option to configure a minimum TLS version. With Saloon v3, Saloon has set this default to **TLS 1.2.** If any of your API integrations require a lower level of TLS security, you can change the Saloon config while your application is loading. + +```php +use Saloon\Config; + +Config::$defaultTlsMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; +``` + +You can [visit this page on the PHP documentation](https://www.php.net/manual/en/function.stream-socket-enable-crypto.php) to see the different TLS options available. + +{% hint style="info" %} +**TLS 1.1** has been deprecated since 2021 so it is unlikely that APIs are still using it, but older systems may have not upgraded yet. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/conclusion/official-book.md b/_docs/laravel-libs/saloon-docs/conclusion/official-book.md new file mode 100644 index 0000000..08d6ba9 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/official-book.md @@ -0,0 +1,13 @@ +# 📘 Official Book! + +
+ +We're super excited to partner with [Ash Allen](https://twitter.com/AshAllenDesign) with his latest book - _Consuming APIs in Laravel**.**_ This book with over 440 pages contains everything you need to build awesome API integrations in Laravel. The book uses Saloon as the tool to build the integrations, so it's a great way to learn Saloon inside out too! + +You'll also learn about the most common types of APIs, How OAuth2 works and how to handle webhooks securely. + +{% hint style="info" %} +Use code **SALOON** at checkout to get **20% off** the "Consuming APIs in Laravel" book or the book bundle with "Battle Ready Laravel"! +{% endhint %} + +[Pick up your copy today at consuming-apis-in-laravel.com!](https://consuming-apis-in-laravel.com/?aff=DGMrX) diff --git a/_docs/laravel-libs/saloon-docs/conclusion/showcase.md b/_docs/laravel-libs/saloon-docs/conclusion/showcase.md new file mode 100644 index 0000000..4357a52 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/showcase.md @@ -0,0 +1,172 @@ +# 🎖 Showcase + +{% hint style="info" %} +Want to add your application or SDK to Saloon's showcase page? Edit this page on Github! 🤠 +{% endhint %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
🚨ohdearapp/ohdear-php-sdk1https://github.com/ohdearapp/ohdear-php-sdk
🌲astrotomic/ecologi-sdk1https://github.com/Astrotomic/ecologi-sdk
🪐astrotomic/tmdb-sdk2https://github.com/Astrotomic/tmdb-sdk
💰myoutdeskllc/salesforce-php3https://github.com/MyOutDeskLLC/SalesforcePhp
🤑sawirricardo/midtrans-apihttps://github.com/sawirricardo/midtrans-api
📃carboneio/carbone-sdk-phphttps://github.com/carboneio/carbone-sdk-php
📞samuelmwangiw/africastalking-laravelhttps://github.com/SamuelMwangiW/africastalking-laravel
💻samuelmwangiw/linodehttps://github.com/SamuelMwangiW/linode
🌱alphaolomi/json-placeholderhttps://github.com/alphaolomi/json-placeholder
💬flourishlabs/saloon-slackhttps://github.com/flourishlabs/saloon-slack
📦alphaolomi/laravel-repmanhttps://github.com/alphaolomi/laravel-repman
📊njoguamos/laravel-plausiblehttps://github.com/njoguamos/laravel-plausible
🧠probots-io/pinecone-phphttps://github.com/probots-io/pinecone-php
🇨🇴felipeva/api-colombia-phphttps://github.com/felipeva/api-colombia-php
🤝deschutesdesigngroupllc/perscom-php-sdkhttps://github.com/DeschutesDesignGroupLLC/perscom-php-sdk
✈️noahnxt/laravel-open-holiday-apihttps://github.com/NoahNxT/laravel-open-holidays-api
💰njoguamos/laravel-pesapalhttps://github.com/njoguamos/laravel-pesapal
🔖oneduo/github-sdk-phphttps://github.com/oneduo/github-sdk-php
💳lloricode/paymaya-sdk-phphttps://github.com/lloricode/paymaya-sdk-php
diff --git a/_docs/laravel-libs/saloon-docs/conclusion/tutorials.md b/_docs/laravel-libs/saloon-docs/conclusion/tutorials.md new file mode 100644 index 0000000..cc00f6e --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/conclusion/tutorials.md @@ -0,0 +1,43 @@ +# 📖 Tutorials & Blog Posts + +### Video Tutorials + +#### Wrangling APIs in the Wild West using Saloon + +{% embed url="https://www.youtube.com/watch?v=ZV00ggpWfBU" %} +Created by Sam Carré +{% endembed %} + +#### Saloon - A PHP package to simplify API integrations + +{% embed url="https://www.youtube.com/watch?v=r3AU6uYQGt4" %} +Created by Andrew Schmelyun +{% endembed %} + +#### Demystifying Saloon: A Step-by-Step Guide + +{% embed url="https://www.youtube.com/watch?v=Pl51BkVTn8M" %} +Created by Ruslan Steiger +{% endembed %} + +#### Integrate an API with Laravel and Saloon (FR) + +{% embed url="https://www.youtube.com/watch?v=8rPXqmBG99c" %} +Created by Nord Coders +{% endembed %} + +## API Integrations using Saloon in Laravel + +Steve McDougall wrote a super in-depth tutorial for building a GitHub integration in Laravel using Saloon that enabled you to see a status of repository workflows. It's a great example of using Saloon and is good to follow if you would like to get started + +[https://laravel-news.com/api-integrations-using-saloon-in-laravel](https://laravel-news.com/api-integrations-using-saloon-in-laravel) + +### Podcast + +Want to \*hear\* more about Saloon? The creator of Saloon, Sam Carré and Jake Bennet recorded an episode all about how Saloon works on the North Meets South podcast. Click on the link below to listen to the podcast episode. + +#### [Listen on their website](https://www.northmeetssouth.audio/112) + +[**Listen on Apple Podcasts**](https://podcasts.apple.com/us/podcast/north-meets-south-web-podcast/id1123508667?i=1000551046555) + +[**Listen on Spotify**](https://open.spotify.com/episode/1oT4LC4bQSx2PNNMQDAkIc?si=b695129aa0d34327\&nd=1) diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/concurrency-and-pools.md b/_docs/laravel-libs/saloon-docs/digging-deeper/concurrency-and-pools.md new file mode 100644 index 0000000..98c0fe0 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/concurrency-and-pools.md @@ -0,0 +1,303 @@ +# 🏎 Concurrency & Pools + +Saloon supports request concurrency and requests pools out of the box. This allows you to make multiple API calls to the same service while keeping the CURL connection open. Under the hood, it uses PHP's cURL multi-handler to keep the connection open, this results in huge speed benefits when making lots of API calls. Saloon's concurrency is powered by [Guzzle's implementation](https://docs.guzzlephp.org/en/stable/quickstart.html?highlight=pool#concurrent-requests) behind the scenes. + +One of Laravel's core members, Nuno Maduro [wrote a great blog post](https://nunomaduro.com/speed\_up\_your\_php\_http\_guzzle\_requests\_with\_concurrency) about request concurrency and its performance with Guzzle directly. The same performance can be shared with Saloon's implementation as Saloon uses Guzzle behind the scenes. + +{% hint style="info" %} +Concurrency is only supported with the `GuzzleSender` and `HttpSender` senders for Saloon. The default sender out of the box with Saloon is the GuzzleSender. +{% endhint %} + +We conducted our own benchmark by making 1,000 API calls to our internal testing API, running on a virtual server with 2 vCPUs and 2GB of RAM. The results were impressive, as all 1,000 API calls were completed in just **2.5 seconds**, a significant improvement compared to 60 seconds when using synchronous requests. + +```php +send(new GetUserRequest); + } +}; + +// ⬇️ Takes 2.5 seconds! 🔥 + +$requests = function () { + for ($i = 0; $i < 1000; $i++) { + yield new GetUserRequest; + } +}; + +$connector->pool($requests, concurrency: 10)->send()->wait(); +``` + +### Getting Started + +Saloon's pooling has been designed specifically to be easy to use. Simply instantiate your connector class and use the `pool` method to create a pool. This method doesn't require any arguments, but you may provide requests, concurrency and handlers right from this method. + +```php +pool( + requests: [], + concurrency: 5, + responseHandler: function () { ... }, + exceptionHandler: function () { ... }, +); + +// Initiate the transfer of requests + +$promise = $pool->send(); + +// Force all the requests to be fulfilled + +$promise->wait(); +``` + +### Available Methods + +* `setRequests(callable|iterable $requests)` +* `getRequests()` +* `withResponseHandler(callable $callable)` +* `withExceptionHandler(callable $callable)` +* `send()` + +### Providing Requests + +The pool class accepts many types of requests: + +* Array of requests +* PHP generator providing requests +* Closure or Invokable class returning an array of requests +* Closure or Invokable class returning a generator + +You may provide these requests into the pool either as the first argument of the `pool` method or using the `setRequests` method. The requests can be instances of `Saloon\Http\Request` or `Saloon\Http\PendingRequest`. + +#### Array of requests + +The simplest way to provide requests to the pool is an array. + +```php +pool([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); + +// Or + +$pool = $forge->pool(); + +$pool->setRequests([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); +``` + +#### Using a PHP generator + +If you are going to send lots of requests you may wish to provide a generator into the pool. This allows you to keep memory consumption low and potentially send hundreds of requests. + +```php + new UserRequest; + } +}; + +$forge = new ForgeConnector; +$pool = $forge->pool($generatorCallback); + +// or + +$pool->setRequests($generatorCallback); +``` + +#### Using a callable or invokable class + +You may wish to use a callable method to return an array of requests or a generator, this is useful if you have any additional logic that needs to execute just before the request pool begins. + +{% tabs %} +{% tab title="Callable" %} +```php +pool($callback); + +// or + +$pool->setRequests($callback); +``` +{% endtab %} + +{% tab title="Invokable Class" %} +```php +pool(new PoolClass); +``` +{% endtab %} +{% endtabs %} + +### Concurrency + +By default, Saloon will send up to 5 requests concurrently. You can customise the concurrency that is used by pools with the `setConcurrency` method. It accepts an integer or a callable like a method or an invokable class in case you want to write advanced logic to determine the concurrency. + +```php +pool(...); + +$pool->setConcurrency(10); + +// or + +$pool->setConcurrency(function () { + return 10; +}); +``` + +### Response Handlers + +When you send requests with pooling, each request is asynchronous, so you cannot guarantee when they are returned. In order to handle the response, Saloon has provided you with two handlers to handle successful requests and failed requests. + +#### Handling Successful Requests + +Any responses that are successful will be handled by the response handler. You may add this with the constructor of your pool or add it once it is created. You can only have one handler. You will get a response instance. + +```php +pool( + requests: [], + concurrency: 5, + responseHandler: function (Response $response) { + // Handle Response + }, +); + +// Or + +$pool->withResponseHandler(function (Response $response) { + // Handle Response +}); +``` + +#### Handling Failed Requests + +When requests fail, they will always be caught with the error handler, even if you don't throw on requests. When a failed request happens you can handle the exception with the `withExceptionHandler` method. + +```php +pool( + requests: [], + concurrency: 5, + exceptionHandler: function (FatalRequestException|RequestException $exception) { + // Handle Exception + }, +); + +// Or + +$pool->withExceptionHandler(function (FatalRequestException|RequestException $exception) { + // Handle Exception +}); +``` + +### Named/Keyed Requests + +Saloon also supports keyed responses to help you easily track exact requests that have been sent. This is especially useful if you are sending requests to different endpoints. You may use keying with arrays or even with a generator. + +```php +pool([ + 'servers' => new GetServersRequest, + 'sites' => new GetSitesRequest, + 'user' => new GetUserRequest, +]); + +// You may access the key in the response and error handlers + +$pool->withResponseHandler(function (Response $response, string $key) { + match($key) { + 'servers' => $this->updateServersList($response), + 'sites' => $this->updateSitesList($response), + 'user' => $this->updateUser($response), + } +}); +``` + +### Sending + +Once you have provided the pool with requests, you are ready to send them. Just use the `send` method on the pool. This will return an instance of `PromiseInterface` . Requests will be handled asynchronously but you can force them to complete with the `wait` method. + +```php +pool([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); + +$pool->withResponseHandler(function (Response $response) { + // Handle Response +}); + +$pool->withExceptionHandler(function (FatalRequestException|RequestException $exception) { + // Handle Exception +}); + +// Initiate the transfer of requests + +$promise = $pool->send(); + +// Force all the requests to be fulfilled + +$promise->wait(); +``` diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/delay.md b/_docs/laravel-libs/saloon-docs/digging-deeper/delay.md new file mode 100644 index 0000000..afdae10 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/delay.md @@ -0,0 +1,75 @@ +# ⏸ Delaying Requests + +Sometimes in your application, you may want to introduce a delay in your requests. This may be to avoid hitting rate limits or to avoid overloading a development environment. With Saloon, you may use the `defaultDelay` and `delay` methods on either your connector or request to define a delay in milliseconds. + +### Default Delay + +You may also wish to define a default delay on your connector or request. You can do this by extending the `defaultDelay` method. + +{% tabs %} +{% tab title="Connector" %} +```php +delay()->set(500); +``` +{% endtab %} + +{% tab title="Request" %} +```php +delay()->set(500); +``` +{% endtab %} +{% endtabs %} + +{% hint style="warning" %} +If you have defined the delay on both the connector and the request, the request delay will take priority. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/middleware.md b/_docs/laravel-libs/saloon-docs/digging-deeper/middleware.md new file mode 100644 index 0000000..68625b8 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/middleware.md @@ -0,0 +1,413 @@ +# 💫 Middleware + +Saloon has a powerful middleware system that allows you to tap into the request and response lifecycle and make any changes you need before the request is sent or the response is given back to the user. This is useful if you want to build your own advanced Saloon integrations or write more advanced logic like generating a unique reference for every request. + +### The Boot Method + +Before we get into Saloon's middleware, there is a useful built-in method on every connector and request that you can utilize. This is the `boot` method. It gets executed every time you send a request. You will get access to the underlying `PendingRequest` instance that the sender will provide to the HTTP client. The boot method is a great way to quickly tap into a pending request and change something like add a header, modify the request body or even trigger events. + +You may extend the public boot method on either your connector or your request. Remember if you use the connector's boot method, every request with that connector will use that boot method. + +You may register middleware inside of the boot method too, which will be used in the rest of the `PendingRequest` lifecycle. + +{% tabs %} +{% tab title="Connector" %} +```php +headers()->add('X-Current-Time', new DateTime); + } +} +``` +{% endtab %} + +{% tab title="Request" %} +```php +headers()->add('X-Current-Time', new DateTime); + } +} +``` +{% endtab %} +{% endtabs %} + +### The PendingRequest + +The `PendingRequest` class is an intermediary class that Saloon uses to populate everything when you send a request. Every time you send a request, a new `PendingRequest` instance is created which prevents your connector or request from being mutated every time a request is sent. The `PendingRequest` class has many of the methods that you are used to seeing on the request/connector for managing headers, query parameters, config, and request body. + +The `PendingRequest` class is used for boot methods, middleware and [plugins](../installable-plugins/traits.md). + +### Request Middleware + +You may also at any point tap into the request lifecycle by using request middleware. Request middleware is useful for changing something on the `PendingRequest` instance before the request is sent like making another request to get an authentication token for the original request. + +On your connector or request, call the `middleware()` method and use the `onRequest()` method. You should provide a callable, like a closure or invokable class. This callable will be given access to the `PendingRequest` instance which can be mutated. + +{% hint style="info" %} +Return values are not required, but you may either return an instance of `PendingRequest` or a `FakeResponse` class for an early fake response. +{% endhint %} + +#### Anonymous Functions + +You can use a regular closure/anonymous function to create a middleware on the fly. + +{% tabs %} +{% tab title="Connector" %} +```php +middleware()->onRequest(function (PendingRequest $pendingRequest) { + $pendingRequest->headers()->add('Authorization', 'Bearer ' . $token); +}); +``` +{% endtab %} + +{% tab title="Request" %} +```php +middleware()->onRequest(function (PendingRequest $pendingRequest) { + $pendingRequest->headers()->add('Authorization', 'Bearer ' . $token); +}); +``` +{% endtab %} +{% endtabs %} + +#### Invokable Classes + +You may also use invokable classes to keep your middleware classes tidy. If you are using invokable middleware classes, you should implement the `RequestMiddleware` interface. + +{% tabs %} +{% tab title="Definition" %} +```php +headers()->add('Authorization', 'Bearer ' . $token); + } +} +``` +{% endtab %} + +{% tab title="Usage (Connector)" %} +```php +middleware()->onRequest(new AuthenticateRequest); +``` +{% endtab %} + +{% tab title="Usage (Request)" %} +```php +middleware()->onRequest(new AuthenticateRequest); +``` +{% endtab %} +{% endtabs %} + +### Early Fake Responses + +You may also choose to tap into Saloon's mock functionality by creating your own fake responses. When you return a `FakeResponse`, the rest of the request middleware will still be processed but the fake response will be stored on the `PendingRequest`. + +If this fake response is present before Saloon sends the request, it won't send the request to the sender, instead, Saloon will use the `FakeResponse`. This is super handy if you want to build your own middleware that stops Saloon from sending real requests, like for caching. + +```php +middleware() + ->onRequest(function (PendingRequest $pendingRequest) { + return new FakeResponse( + body: ['data' => 'Fake Data!'], + status: 200, + headers: [] + ); + }); +``` + +{% hint style="warning" %} +Even though you are returning a `FakeResponse` class, the next middleware will still receive the PendingRequest instance. Additionally, if another middleware also returns a fake response, the latest one will be used. +{% endhint %} + +### Response Middleware + +Once you have sent your request, even if it's a fake response, Saloon will send the response down the response middleware pipeline. You may add your own response middleware to change the response class or do something like log responses. + +On your connector or request, you can call the `middleware()` method and use the `onResponse()` method. You should provide a callable, like a closure or invokable class. This callable will be given access to the `Response` instance. + +{% hint style="info" %} +Return values are not required, but you may return an instance of `Saloon\Http\Response` to overwrite the response class in the middleware. +{% endhint %} + +#### Anonymous Functions + +You can use a regular closure/anonymous function to create a middleware on the fly. + +{% tabs %} +{% tab title="Connector" %} +```php +middleware()->onResponse(function (Response $response) { + Logger::recordResponse($response); +}); +``` +{% endtab %} + +{% tab title="Request" %} +```php +middleware()->onResponse(function (Response $response) { + Logger::recordResponse($response); +}); +``` +{% endtab %} +{% endtabs %} + +#### Invokable classes + +Similar to request middleware, you can also create invokable middleware classes for response middleware. You should use the `ResponseMiddleware` contract to ensure your invokable class has the correct signature. + +{% tabs %} +{% tab title="Definition" %} +```php +middleware()->onResponse(new LogResponse); +``` +{% endtab %} + +{% tab title="Usage (Request)" %} +```php +middleware()->onResponse(new LogResponse); +``` +{% endtab %} +{% endtabs %} + +### Using Constructors + +While registering middleware on the fly is really useful, it often leads to repeated code. If you would like your connector to always have a specific request or response middleware you should use the `boot` method described above, or use the constructor of your connector or request. + +```php +middleware()->onRequest(new AuthenticateRequest); + $this->middleware()->onResponse(new LogResponse); + } +} +``` + +{% hint style="danger" %} +Be cautious using anonymous non-static closures inside the constructor/boot method. This may cause issues like Saloon not being able to close connections properly. [Click here to read more.](../conclusion/known-issues.md#usage-of-anonymous-functions-with-long-running-processes-like-laravel-queues) +{% endhint %} + +### Using Plugins + +Plugins are another useful feature for Saloon that allows you to extend Saloon and tap into the middleware from traits. This is especially useful if you intend to use the trait on multiple requests or connectors. + +[Read through the plugins page for more information.](../installable-plugins/traits.md) + +### Middleware Naming + +You can choose to name your middleware. Each name must be unique to the given pipeline. For example, you cannot have two middleware with the same name on the request pipeline, but you could have the same name used once for the request pipeline and once for the response pipeline. Use the second argument to specify a name. + +```php +middleware()->onResponse(new LogResponse, 'logResponse'); +``` + +### Global Middleware + +Saloon also supports adding global middleware. You most likely won't need this level of granularity but if you do, you may use the `Config` class. When using global middleware, you should make sure to name your middleware so it isn't accidentally registered twice. + +```php +onResponse(new LogResponse, 'logResponse'); +``` + +{% hint style="danger" %} +Be cautious with global middleware. Since it uses a static property behind the scenes, the value is kept between tests when running a full test suite. You can use the `Config::clearGlobalMiddleware()` method to get around this issue. +{% endhint %} + +### Middleware Execution Order + +The following is the order in which middleware is executed. + +1. Global middleware (Like the Laravel plugin) +2. Mock client finds a fake response (if present) +3. Plugin middleware +4. User-added middleware +5. Debugging middleware is run (for the final object) + +### Choosing When Your Middleware Is Executed + +You may choose to change when your middleware is executed. For example, you might want to run something at the very end of all the other middleware that has been run. This is especially useful if you are building a plugin for people to install in Saloon and require the final request object before it is sent. You can use the third argument to specify an order. This expects a `PipeOrder` enum and allows you to choose either `FIRST` or `LAST`. + +When the middleware is executed, any middleware marked as "first" will run first, and any that have been marked as "last" will be executed last. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\PendingRequest;
+use Saloon\Enums\PipeOrder;
+
+class GetServersRequest extends Request
+{
+    // { ... }
+    
+    public function boot(PendingRequest $pendingRequest): void
+    {
+        $request->middleware()->onRequest(new RecordResponse, order: PipeOrder::LAST);
+    }
+}
+
+ +### Middleware Caveats + +Here are some known caveats that you should know about when using Saloon's middleware. + +* You cannot add request middleware from inside of another request middleware**,** but you can add response middleware inside of the onRequest() middleware method. +* You cannot add response middleware from inside of another response middleware. +* You may return a fake response in request middleware but you will always get a PendingRequest back + +### Guzzle Handlers / Middleware + +With previous versions of Saloon, you could add Guzzle middleware or "handlers" directly to the connector or request. From version two, Saloon is now sender-agnostic, so the `addHandler` method has been removed but you may still add Guzzle middleware if you are using the `GuzzleSender` (the default sender with Saloon) + +### Adding Guzzle Middleware + +You can add middleware to the Guzzle client by using the `sender` method on the connector. You must only add Guzzle middleware directly on your connector with your constructor method. This is because Saloon only instantiates the sender once, so in order to prevent middleware from being registered multiple times, it should be placed in the constructor. + +```php +sender()->addMiddleware(function (callable $handler) { + return function (RequestInterface $request, array $options) use ($handler) { + $request->withHeader('X-Custom-Header', 'Hello'); + + return $handler($request, $options); + }; + }) + } +} +``` + +{% hint style="info" %} +To read more about Guzzle's middleware and handlers [click here](https://docs.guzzlephp.org/en/stable/handlers-and-middleware.html). +{% endhint %} + +### Accessing The Underlying Guzzle Instance + +You may need to modify the Guzzle client or the handler stack. If you need to do this, you can use the `getGuzzleClient` or `getHandlerStack` methods. + +```php +sender()->getGuzzleClient(); + + $handlerStack = $this->sender()->getHandlerStack(); + } +} +``` diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/README.md b/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/README.md new file mode 100644 index 0000000..4ef168f --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/README.md @@ -0,0 +1,19 @@ +# 🔑 OAuth2 Authentication + +Saloon supports some OAuth2 authentication grants out of the box which you can use in your application. They come in the form of traits that can be easily added to your connector and then configured to your needs. Read more below by finding the grant type you would like to use + +### Authorization Code Grant + +This flow is the typical process where your application redirects your users to a third party to approve your authentication request. After they have approved the authentication request, they will be redirected back to your application where you can generate access tokens. + +{% content-ref url="oauth2-authentication.md" %} +[oauth2-authentication.md](oauth2-authentication.md) +{% endcontent-ref %} + +### Client Credentials Grant + +This flow is often used for internal server-to-server authentication. Like a shopping website communicating with an internal warehouse API. You are often given a single access token which can be used to generate access tokens. + +{% content-ref url="client-credentials-grant.md" %} +[client-credentials-grant.md](client-credentials-grant.md) +{% endcontent-ref %} diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/client-credentials-grant.md b/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/client-credentials-grant.md new file mode 100644 index 0000000..7579106 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/oauth2-authentication/client-credentials-grant.md @@ -0,0 +1,254 @@ +# Client Credentials Grant + +Some API providers implement the OAuth2 _Client Credentials Grant_ for authentication. Implementing this grant type every time you create a new API integration can be tedious and time-consuming. Saloon offers a simple, extendable OAuth2 trait to help you get up and running quickly. + +### Prerequisites + +This section of the documentation assumes that you are familiar with OAuth2 and specifically the _Client Credentials Grant_. If you are not familiar with how this grant type works, [Auth0 has a great explanation on its website.](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) + +### Flow Example + +Saloon has provided methods for the full client credentials grant. + +```php +$connector = new WarehouseConnector; + +// 1. Create an access token authenticator + +$authenticator = $connector->getAccessToken($scopes); + +// 2. Authenticate the connector + +$connector->authenticate($authenticator); + +// 3. Send your requests + +$connector->send(new GetInventoryRequest); +``` + +### Getting Started + +Let's start with preparing our connector to support the client credentials grant. All we have to do is add the `ClientCredentialsGrant` trait to our connector. + +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setDefaultScopes(['inventory.read']) + ->setTokenEndpoint('/oauth/token') + ->setRequestModifier(function (Request $request) { + // Optional: Modify the requests being sent. + }); + } +} +``` + +{% hint style="info" %} +The endpoint method, like `setTokenEndpoint` on the OAuthConfig class supports full URLs if you need to overwrite the base URL on the connector however you may just use the endpoint if the base URL is the same. +{% endhint %} + +#### Overwriting the OAuth2 config + +Sometimes, you may have a different OAuth2 client ID and secret for each user of your application. If your OAuth2 config is dependent on a per-user/tenant basis, it's recommended that you pass in the credentials as constructor arguments of your connector and then set the `oauthConfig` inside the constructor. + +In the following example, I will pass in the `$clientId` and the `$clientSecret` as constructor arguments and overwrite the OAuth2 config. + +```php +oauthConfig()->setClientId($clientId); + $this->oauthConfig()->setClientSecret($clientSecret); + } + + // ... +} +``` + +### Creating Access Tokens + +You are now ready to create access tokens. You should use the `getAccessToken` method on your connector. If successful, the method will return an `AccessTokenAuthenticator`. The access token and expiry (if provided) are wrapped up in a [Saloon Authenticator](../../the-basics/authentication.md#custom-authenticators) class that can be used to authenticate your connector/requests. It acts like a DTO that can be easily serialized and transported around your application. + +```php +getAccessToken(); + +// Use authenticator to authenticate your connector instance + +$connector->authenticate($authenticator); + +// Any request sent through this connector will now have authentication applied + +$connector->send(new GetInventoryRequest); +``` + +{% hint style="info" %} +Once you have received the authenticator instance, you should cache it securely in your application for future use. Read further to see how you can do this. +{% endhint %} + +#### Custom Scopes + +Sometimes you may need to provide an additional "scope" to declare the level of access that your token needs. You may provide default scopes in the OauthConfig class on your connector, but you can also provide additional scopes when creating access tokens. Saloon will separate scopes with spaces but if your API integration requires scopes to be separated any other way, you can specify this with the `scopeSeparator` argument. + +```php +getAccessToken( + scopes: ['inventory.update', 'inventory.delete'], + scopeSeparator: '+', +); +``` + +#### Returning Responses + +If you prefer, you may request Saloon to return a `Saloon\Http\Resonse` instance instead of a `AccessTokenAuthenticator` when creating access tokens. To use responses, just provide the `returnResponse` argument when creating access tokens. + +```php +getAccessToken( + returnResponse: true, +); +``` + +### Authenticator Methods + +The authenticator returned by Saloon when using the `getAccessToken` method will contain the Access Token, and optionally an expiry date that was returned by the OAuth2 server. You can access these properties with the following methods. You can also check if the authenticator has expired, which will come in handy when refreshing access tokens. + +```php +getAccessToken(); +$authenticator->getExpiresAt(); + +$authenticator->hasExpired(); +$authenticator->hasNotExpired(); +``` + +### Customising The Authenticator + +Sometimes the API provider you are authenticating with may require additional information to be used in the authenticator. You can customise how the authenticator will be created by extending the `createAccessTokenAuthenticator` method on your connector. + +```php +object(); + + $accessToken = $responseData->access_token; + $expiresAt = new DateTimeImmutable('+' . $responseData->expires_in . ' seconds'); + + return $this->createOAuthAuthenticator($accessToken, $expiresAt); +} +``` + +### Customising The Requests + +Sometimes you might integrate with an API that requires additional query parameters or headers to be sent with the OAuth2 flow. You may use the `requestModifier` method on the `getAccessToken` method or use the `setRequestModifier` method within the `OAuthConfig` to add a callable that is invoked before a request is sent. + +{% tabs %} +{% tab title="Per Request" %} +```php +getAccessToken(requestModifier: function (Request $request) { + $request->query()->add('access_type', 'offline'); +}); +``` +{% endtab %} + +{% tab title="All Requests" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\OAuth2\GetClientCredentialsTokenRequest;
+
+protected function defaultOauthConfig(): OAuthConfig
+{
+    return OAuthConfig::make()
+        ->setClientId('my-client-id')
+        ->setClientSecret('my-client-secret')
+        ->setRequestModifier(function (GetClientCredentialsTokenRequest $request) {
+            //
+        }),
+}
+
+{% endtab %} +{% endtabs %} + +### Using your own request classes + +There are situations where Saloon's own request classes for getting the access token might not suit the API you are integrating with. For example, if an API uses JSON encoding instead of form encoding. You may use the following method on your connector to overwrite the instantiation process of the request class. + +```php +getAuthorizationUrl($scopes, $state); + +// 2. Handle the callback from the API provider and create an access token... + +$authenticator = $connector->getAccessToken($code, $state); + +// 3. Authenticate the connector + +$connector->authenticate($authenticator); + +// 4. Send your requests + +$connector->send(new GetTracksRequest); + +// 5. Refresh your access tokens... + +$newAuthenticator = $connector->refreshAccessToken($authenticator); +``` + +### Getting Started + +Let’s start with preparing our connector to support the Authorization Code Flow. All we have to do is add the `AuthorizationCodeGrant` trait to our connector. + +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setDefaultScopes(['user-read-currently-playing']) + ->setRedirectUri('https://my-app.saloon.dev/auth/callback') + ->setAuthorizeEndpoint('https://accounts.spotify.com/authorize') + ->setTokenEndpoint('https://accounts.spotify.com/api/token') + ->setUserEndpoint('/me') + ->setRequestModifier(function (Request $request) { + // Optional: Modify the requests being sent. + }); + } +} +``` + +{% hint style="info" %} +Each of the endpoint methods, like `setAuthorizeEndpoint`on the OAuthConfig class support full URLs if you need to overwrite the base URL on the connector however you may just use the endpoint if the base URL is the same. +{% endhint %} + +#### Overwriting the OAuth2 config + +Sometimes, you may have a different OAuth2 client ID and secret for each user of your application. If your OAuth2 config is dependent on a per-user/tenant basis, it's recommended that you pass in the credentials as constructor arguments of your connector and then set the `oauthConfig` inside the constructor. + +In the following example, I will pass in the `$clientId` and the `$clientSecret` as constructor arguments and overwrite the OAuth2 config. + +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\Traits\OAuth2\AuthorizationCodeGrant;
+
+class SpotifyConnector extends Connector
+{
+    use AuthorizationCodeGrant;
+
+    public function __construct(string $clientId, string $clientSecret)
+    {
+        $this->oauthConfig()->setClientId($clientId);
+        $this->oauthConfig()->setClientSecret($clientSecret);
+    }
+
+    // ...
+}
+
+ +### Creating an Authorization URL + +Now we have setup our connector to support the authorization code grant, we are ready to start the OAuth2 process. Usually, the first stage is to generate a URL to redirect our application users to. To generate an authorization URL, you can use the `getAuthorizationUrl` method on the connector. + +```php +getAuthorizationUrl(); +``` + +You can also pass in scopes which will be merged with the default scopes if you provided them in the OAuth config. Saloon will separate scopes with spaces but if your API integration requires scopes to be separated any other way, you can specify this with the `scopeSeparator` argument. + +```php +$authorizationUrl = $connector->getAuthorizationUrl( + scopes: ['user-library-read'], + scopeSeparator: '+', +); +``` + +You can also provide additional query parameters if you need to with the `additionalQueryParameters` argument. This should be a key-value array where the key is the query parameter name and the value is the value of the query parameter. + +```php +$authorizationUrl = $authConnector->getAuthorizationUrl( + additionalQueryParameters: [ + 'username' => 'JohnWayne' + ], +); +``` + +#### State + +To help prevent CSRF attacks or send additional data during authentication, you can pass an additional unique string in your authorization URL that the API's OAuth2 server will send back to you after your user has approved or denied access to your OAuth2 app. + +```php +$authorizationUrl = $authConnector->getAuthorizationUrl( + state: 'application-user-id', +); +``` + +If you do not provide your own state, Saloon will automatically generate a unique, 32-character string. Once you have generated the authorization URL, you can then use the `getState` method on your connector to get the state back. You should store this string in your application's session or cache to be verified later. + +
<?php
+
+$connector = new SpotifyConnector;
+$authorizationUrl = $connector->getAuthorizationUrl();
+
+$state = $authConnector->getState(); // '8484b43fdjfdnfdj3llls...'
+
+ +### Creating Access Tokens + +After the user has approved your application, the API provider will redirect you back to your application with an authorization code and state. This data usually sent in the form of query parameters should be passed into your `getAccessToken` method on your connector. If successful, the method will return an `AccessTokenAuthenticator`. The access token, refresh token and expiry are wrapped up in a [Saloon Authenticator](../../the-basics/authentication.md#custom-authenticators) class that can be used to authenticate your connector/requests. It acts like a DTO that can be easily serialized and transported around your application. + +
<?php
+
+$connector = new SpotifyConnector;
+$authenticator = $authConnector->getAccessToken($code);
+
+// Use authenticator to authenticate your connector instance
+
+$connector->authenticate($authenticator);
+
+// Any request sent through this connector will now have authentication applied
+
+$connector->send(new GetTracksRequest);
+
+ +{% hint style="info" %} +Once you have received the authenticator instance, you should cache it securely in your application for future use. Read further to see how you can do this. +{% endhint %} + +#### Verifying State + +If you stored the state that was generated during creating an authorization URL, you should pass this expected state alongside the state sent back by the API provider's OAuth2 server. This will be used to verify the state provided back by the application is valid. If the state does not match the expected state, Saloon will throw an exception. + +```php +getAccessToken($code, $state, $expectedState); +``` + +### Storing Authentication For Later + +You will likely need to store the authenticator securely so you can use it for future requests. You may serialize and unserialize the authenticator class using the helper methods below, then you can store the string wherever you like, usually encrypted in the database if it's against a user. Then, you can retrieve this authenticator and use it to authenticate your connector. + +```php +getAccessToken($code); + +// Securely store this against your user. + +$serialized = $authenticator->serialize(); + +// Unserialize the authenticator when retrieving it + +$authenticator = AccessTokenAuthenticator::unserialize($serialized); +``` + +### Authenticator Methods + +The authenticator returned by Saloon when using the `getAccessToken` or `refreshAccessToken` methods will contain the Access Token, Refresh Token and Expiry Date that was returned by the OAuth2 server. You can access these properties with the following methods. You can also check if the authenticator has expired, which will come in handy when refreshing access tokens. + +```php +getAccessToken(); +$authenticator->getRefreshToken(); +$authenticator->getExpiresAt(); + +$authenticator->hasExpired(); +$authenticator->hasNotExpired(); +``` + +### Refreshing Access Tokens + +When retrieving your authenticator out of storage, you should always check if the access token has expired and if it needs refreshing. If the authenticator's access token has expired, you can call the `refreshAccessToken` method which will create a fresh authenticator. + +In this example, `$user` is the user of my application and I have written methods to get and store the authenticators. + +```php +getCachedAuthenticator(); +$connector = new SpotifyConnector; + +if ($authenticator->hasExpired()) { + // We'll refresh the access token which will return a new authenticator + // which we can store against our user in our application. + + $authenticator = $connector->refreshAccessToken($authenticator); + $user->updateAuthenticator($authenticator); +} + +// Authenticate our connector and send the request + +$connector->authenticate($authenticator); + +$response = $connector->send(new GetTracksRequest); +``` + +{% hint style="info" %} +If you are using Laravel and the Saloon Laravel library, you can use built-in `EncryptedOAuthAuthenticatorCast` **/** `OAuthAuthenticatorCast` Eloquent casts to automatically cast the authenticator for storing in your database. +{% endhint %} + +### Customising The Authenticator + +Sometimes the API provider you are authenticating with may require additional information to be used in the authenticator. You can customise how the authenticator will be created by extending the `createAccessTokenAuthenticator` method on your connector. + +```php +object(); + + $accessToken = $responseData->access_token; + $refreshToken = $responseData->refresh_token ?? $fallbackRefreshToken; + $expiresAt = new DateTimeImmutable('+' . $responseData->expires_in . ' seconds'); + + return $this->createOAuthAuthenticator($accessToken, $refreshToken, $expiresAt); +} +``` + +### Customising The Requests + +Sometimes you might integrate with an API that requires additional query parameters or headers to be sent with the OAuth2 flow. You may use the `requestModifier` property on the methods or use the `setRequestModifier` method within the `OAuthConfig` to add a callable that is invoked before a request is sent. + +{% tabs %} +{% tab title="Per Request" %} +```php +getAccessToken($code, requestModifier: function (Request $request) { + $request->query()->add('access_type', 'offline'); +}); + +$connector->getRefreshToken($code, requestModifier: function (Request $request) { + $request->headers()->add('X-App-Key', $appKey); +}); + +$connector->getUser($code, requestModifier: function (Request $request) { + $request->headers('Accept', 'text/plain'); +}); +``` +{% endtab %} + +{% tab title="All Requests" %} +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setRedirectUri('https://my-app.saloon.dev/auth/callback') + ->setRequestModifier(function (Request $request) { + // This callback is invoked on every request, so you + // may want to use if-statements or a match statement + // to apply conditions based on request. + + if ($request instanceof GetAccessTokenRequest) { + $request->query()->add('access_type', 'offline'); + } + + if ($request instanceof GetRefreshTokenRequest) { + $request->headers()->add('X-App-Key', $appKey); + } + + if ($request instanceof GetUserRequest) { + $request->headers('Accept', 'text/plain'); + } + }), +} +``` +{% endtab %} +{% endtabs %} + +### Using your own request classes + +There are situations where Saloon's own request classes for getting the access token, refreshing the access token or getting the user might not suit the API you are integrating with. For example, if an API uses JSON encoding instead of form encoding. You may use the following methods on your connector to overwrite the instantiation process of the request classes. + +```php +getAccessToken( + returnResponse: true, +); + +$response = $connector->refreshAccessToken( + returnResponse: true, +); +``` + +### Real-world example + +If you would like to see an example integration using the OAuth2 methods mentioned above, you can see the following Laravel application. + +[https://github.com/Sammyjo20/saloon-v2-spotify-example](https://github.com/Sammyjo20/saloon-v2-spotify-example) diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/README.md b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/README.md new file mode 100644 index 0000000..7ac2a9e --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/README.md @@ -0,0 +1,412 @@ +# 📚 Pagination + +When building API integrations, you may encounter a scenario where the server does not provide all the results in a single list. Instead, it divides the results into several pages. This strategy is called pagination, and integrating it into your application can be tedious and repetitive. With Saloon, you can install this pagination plugin to reduce the boilerplate code and iterate through every result across _every_ page in one loop. **It's like magic!** Saloon has three paginators out of the box to support the most common types of pagination: + +* **Paged pagination** - where you have to specify the next page as a query parameter (?page=1, ?page=2 and so on) +* **Limit/Offset pagination** - where you must specify two query parameters - a limit and an offset. +* **Cursor pagination** - where each page will return a "cursor" (a string) that you use to query the next page. + +Saloon's paginators are custom [PHP iterators](https://www.php.net/manual/en/class.iterator.php)_,_ meaning they can be used in for-loops. They are also memory efficient, so they only keep one page in memory at a time, this means you can use Saloon's paginators to iterate through **thousands of pages and millions of results without running out of memory**. + +Additionally, Saloon's paginators have a few really useful methods to traverse through the results, like mapping them into Laravel's famous "Collection" class or simply an array of results. Here's how the pagination looks in your application: + +```php +paginate(new GetLikedSongsRequest); + +foreach($likedSongs->items() as $likedSong) { + // e.g. Luke Combs - When It Rains It Pours 🎵 +} +``` + +{% hint style="info" %} +Saloon's paginators are versatile and can work with any API format, including JSON, XML, and even multipart responses. +{% endhint %} + +### Getting Started + +Saloon's paginators are provided through a plugin. First, install the following package with Composer. + +```sh +composer require saloonphp/pagination-plugin "^2.0" +``` + +### Making your requests pageable + +Once the pagination plugin is installed, you must implement an interface on the requests that use pagination. This interface enables the paginator to decide whether or not to try pagination. It's important to do this as it avoids developer mistakes and potentially causing infinite loops. + +All you need to do is add the `Paginatable` interface to your requests. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\PaginationPlugin\Contracts\Paginatable;
+
+class GetLikedSongsRequest extends Request implements Paginatable
+{
+    // ...
+}
+
+ +After that, you need to add the `HasPagination` interface to your connector. This will require you to define a `paginate` method which we will implement next. + +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\Paginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): Paginator
+    {
+        //
+    }
+}
+
+ +Now you need to choose a paginator that corresponds to the pagination type used by the third-party API. This documentation is divided into three sections based on Saloon's three pre-installed paginators. + +{% content-ref url="paged-pagination.md" %} +[paged-pagination.md](paged-pagination.md) +{% endcontent-ref %} + +{% content-ref url="limit-offset-pagination.md" %} +[limit-offset-pagination.md](limit-offset-pagination.md) +{% endcontent-ref %} + +{% content-ref url="cursor-pagination.md" %} +[cursor-pagination.md](cursor-pagination.md) +{% endcontent-ref %} + +### Building Your Own Paginators + +Sometimes an API may implement their own kind of pagination and Saloon might not have a pagination supported out of the box for it. You can create your own paginators really easily. Follow the link below for building your own paginators. + +{% content-ref url="custom-pagination.md" %} +[custom-pagination.md](custom-pagination.md) +{% endcontent-ref %} + +### Using The Paginator + +After you have configured your paginator, it's time to start using it! There are various ways to use the paginator, so we'll cover them in this part of the guide. First, let's take a look at how we instantiate our paginator. When we instantiate the paginator - Saloon won't make any requests. The requests are only made when we start iterating over the paginator. + +```php +paginate(new GetLikedSongsRequest); +``` + +As you can see, instantiating the paginator is as simple as running the method and passing in the paginatable request. We are now ready to start using the paginator. + +#### Iterating Over Responses + +The simplest way to start using the paginator is to use it inside of a `foreach` loop. This will return each page as a Saloon `Response` for you to access. Saloon will only keep one response in memory at a time so you won't have to worry about running out of memory. + +```php +paginate(new GetLikedSongsRequest); + +foreach($paginator as $response) { + $status = $response->status(); + $data = $response->body(); +} +``` + +#### Iterating Over Items + +One of the more exciting methods Saloon provides is the `items` method. This cool method will give you each item across multiple pages. With this, you can handle the individual items. This uses the `getPageItems` method which you defined earlier in your paginator. + +```php +paginate(new GetLikedSongsRequest); + +foreach($paginator->items() as $song) { + $songName = $song['name']; + $songArtists = $song['artists']; +} +``` + +#### Using Laravel Collections (LazyCollection) + +Another really cool method Saloon provides is the `collect` method. If you are using Laravel with Saloon, this method will work out of the box, but if you aren't using Laravel - you can add the support for this method by installing the "collections" library via Composer. + +```bash +composer require illuminate/collections +``` + +This method will return a `LazyCollection` class. This class extends Laravel's base `Collection` class but works with custom iterators and keeps memory consumption low. The `LazyCollection` is really powerful when it comes to processing results from a paginated API. You can use the collection to filter, map, sort and much more all within just one iteration! + +```php +paginate(new GetLikedSongsRequest); +$collection = $paginator->collect(); + +$results = $collection + ->filter(function (array $song) { + return count($song['artists']) > 1; + }) + ->map(function (array $song) { + return $song['name']; + }) + ->sort(); + +foreach($results as $song) { + // $song: "When It Rains It Pours" +} +``` + +Even though in this example, we are doing multiple operations (filter, map, sort) the transformation will only happen when we iterate through the `LazyCollection` making it very performant and easy on system memory. + +By default, Saloon will iterate through each result within each API page, but if you would rather have a collection that iterates through `Response` classes, you may do this too. Just set the `throughItems` argument to false. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$collection = $paginator->collect(throughItems: false);
+
+ +{% hint style="info" %} +To see a full list of available methods on the `LazyCollection` you can [click here to read](https://laravel.com/docs/collections) the Laravel Documentation on Collections. +{% endhint %} + +### Advanced Features + +Saloon's paginators are a fantastic way of iterating through many page-separated results quickly and easily without writing boilerplate code in your application. So far we've covered the basics of pagination, but there's still plenty you can do. Within this section of the guide, we'll go through some more advanced features. + +#### Casting Items Into DTOs + +Saloon has a great way of casting responses into DTOs, but what if instead of getting the raw array or string item for each item in the paginator you wanted to resolve your DTO? You can simply use your `dto` or `dtoOrFail` method inside of the `getPageItems` method of your paginator. By using this method, you already have configured your DTO building logic on your connector. If you're not sure how to do this, [click here](../../the-basics/data-transfer-objects.md). + +{% tabs %} +{% tab title="Paginator Config" %} +
class SpotifyConnector extends Connector implements HasPagination
+{
+    public function paginate(Request $request): PagedPaginator
+    {
+        return new class(connector: $this, request: $request) extends PagedPaginator
+        {
+            // ...
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->dto();
+            }
+        }
+    }
+}
+
+{% endtab %} + +{% tab title="Request" %} +
<?php
+
+class GetLikedSongsRequest extends Request
+{
+    // {...}
+    
+    public function createDtoFromResponse(Response $response): array
+    {
+        return array_map(function (array $song) {
+            return Song::fromArray($song);
+        }, $response->json('items'));
+    }
+}
+
+{% endtab %} +{% endtabs %} + +{% hint style="info" %} +The `createDtoFromResponse` method on your request/connector must return an array. +{% endhint %} + +You can also implement the DTO conversion logic inside of the `getPageItems` method like below. + +```php +protected function getPageItems(Response $response, Request $request): array +{ + return array_map(function (array $song) { + return Song::fromArray($song); + }, $response->json('items')); +} +``` + +#### Asynchronous Pagination / Pooling + +You may prefer to send your requests asynchronously or use a request pool for better performance. To get started with this, you must implement a new method on your paginator called `getTotalPages`. This method is invoked after the first request and is used to determine how many additional requests Saloon needs to send. + +Let's start with defining our `getTotalPages` method. Some APIs may not return this information, and unfortunately, if they do not return this information then you may not be able to do asynchronous pagination. + +
<?php
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    public function paginate(Request $request): PagedPaginator
+    {
+        return new class(connector: $this, request: $request) extends PagedPaginator
+        {
+            // ...
+            
+            protected function getTotalPages(Response $response): int
+            {
+                return $response->json('total_results');
+            }
+        }
+    }
+}
+
+ +Next, instantiate your paginator and use the `async` method to enable asynchronous pagination. Now when you iterate through results, you will get a `Promise` instance instead of a Saloon Response. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$paginator->async();
+
+foreach($paginator as $promise) {
+    // $promise->then()
+}
+
+ +You can also use a paginator pool. If you are unfamiliar with how asynchronous request pools work, [check out this section of the documentation](../concurrency-and-pools.md) first. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$pool = $paginator->pool(concurrency: 10);
+
+$pool->withResponseHandler(function (Response $response) { 
+    // Handle each response
+
+    $status = $response->status();
+    $data = $response->body(); 
+});
+
+$promise = $pool->send();
+
+$promise->wait();
+
+ +#### Custom Per-Request Pagination + +Sometimes you may wish to use a different paginator on your request than your connector. For example, an API might not use the same pagination across all its endpoints. To get started with this - first, implement the `HasRequestPagination` interface on your request. This interface will expect you to define a `paginate` method on your request. + +```php +json('next_page_url')); + } + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +Next, you can pass the connector into your request to instantiate the paginator. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+$request = new GetLikedSongsRequest;
+
+$paginator = $request->paginate($spotifyConnector);
+
+ +#### Counting results + +You may wish to count the pages of the paginator. You can use the `count()` PHP method to get the total number of pages from a paginator. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$pages = count($paginator);
+
+ +{% hint style="warning" %} +You should use the `count()` method and not `iterator_count()` on the paginator because `iterator_count()` is not supported and you may get inaccurate results. +{% endhint %} + +#### Handling Infinite Loops + +While building your paginators, sometimes, you might run into a situation when the paginator is attempting to get the same page over and over again, causing an infinite loop. This is usually caused by mis-configuring the `isLastPage` method. To try to mitigate infinite loops, the paginator has a built-in safety feature that will throw an exception if the last five responses have exactly the same body. + +Saloon will throw a `PaginationException` with a message like: + +> Potential infinite loop detected! The last 5 requests have had exactly the same body. + +If you would like to disable this check, you can set the `detectInfiniteLoop` property on your paginator to false. + +
public function paginate(Connector $connector): Paginator;
+{
+    return new class(connector: $connector, request: $this) extends PagedPaginator
+    {
+        protected bool $detectInfiniteLoop = false;
+    }
+}
+
+ +{% hint style="warning" %} +Detecting infinite loops with asynchronous pagination is not supported. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/cursor-pagination.md b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/cursor-pagination.md new file mode 100644 index 0000000..8f35d27 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/cursor-pagination.md @@ -0,0 +1,156 @@ +# Cursor Pagination + +First, you will want to import the `CursorPaginator` class and return a new anonymous class that extends Saloon's `CursorPaginator`. This class expects the connector and request to be passed in via the constructor arguments. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\CursorPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): CursorPaginator
+    {
+        return new class(connector: $this, request: $request) extends CursorPaginator
+        {
+            //
+        };
+    }
+}
+
+ +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define three protected methods which are used to power the paginator. These methods are: + +* **getNextCursor** - This method is used to find the next cursor from the response. This method must return either an integer or a string. The next cursor is used in the next request to get a different page. +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement these three methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\CursorPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): CursorPaginator
+    {
+        return new class(connector: $this, request: $request) extends CursorPaginator
+        {
+            protected function getNextCursor(Response $response): int|string
+            {
+                return $response->json('next_cursor');
+            }
+        
+            protected function isLastPage(Response $response): bool
+            {
+                return is_null($response->json('next_cursor'));
+            }
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+        };
+    }
+}
+
+ +Let's assume in this hypothetical example that the API provides a `next_cursor` property in the JSON response. We'll return the value of this property in the `getNextCursor` method. After that, we need to tell Saloon when to stop paginating. We'll use the same `next_cursor` property again. If it's null, we know that there isn't another page to look up. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): CursorPaginator
+{
+    return new class(connector: $this, request: $request) extends CursorPaginator
+    {
+        protected ?int $perPageLimit = 100;
+        
+        // ...
+    }
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the CursorPaginator** + +The CursorPaginator will apply pagination by sending two **query parameters**: + +* cursor +* per\_page + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects a "pageCursor" and a "pageSize" instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): CursorPaginator
+{
+    return new class(connector: $this, request: $request) extends CursorPaginator
+    {
+        protected function getNextCursor(Response $response): int|string
+        {
+            return $response->json('next_cursor');
+        }
+    
+        protected function isLastPage(Response $response): bool
+        {
+            return is_null($response->json('next_cursor'));
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            if ($this->currentResponse instanceof Response) {
+                $request->query()->add('pageCursor', $this->getNextCursor($this->currentResponse));
+            }
+    
+            if (isset($this->perPageLimit)) {
+                $request->query()->add('pageSize', $this->perPageLimit);
+            }
+    
+            return $request;
+        }
+    };
+}
+
+ +### **Useful Properties On The CursorPaginator** + +We previously mentioned that the CursorPaginator class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **page** - An integer which will return the current page that the paginator is currently on. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/custom-pagination.md b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/custom-pagination.md new file mode 100644 index 0000000..41c1331 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/custom-pagination.md @@ -0,0 +1,119 @@ +# Custom Pagination + +If you are building an integration with a third-party API that does not use paged, limit/offset or cursor pagination, you can build your own paginator. Saloon's base paginator class has been designed to be flexible and easy to build against. + +### Getting Started + +First, you will want to import the `Paginator` abstract class and return a new anonymous class that extends Saloon's `Paginator`. This class expects the connector and request to be passed in via the constructor arguments. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\Paginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+
+    public function paginate(Request $request): Paginator
+    {
+        return new class(connector: $this, request: $request) extends Paginator
+        {
+            //
+        };
+    }
+}
+
+ +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define three protected methods which are used to power the paginator. These methods are: + +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. +* **applyPagination** - This method is used to change each request to apply the pagination for the next page. + +Let's implement these three methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\Paginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+
+    public function paginate(Request $request): Paginator
+    {
+        return new class(connector: $this, request: $request) extends Paginator
+        {
+            protected function isLastPage(Response $response): bool
+            {
+                return is_null($response->json('next_page_url'));
+            }
+
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+
+            protected function applyPagination(Request $request): Request
+            {
+                $request->headers()->add('X-Page', $this->currentPage);
+
+                $request->headers()->add('X-Per-Page', $this->perPageLimit);
+
+                return $request;
+            }
+        };
+    }
+}
+
+ +Let's assume in this hypothetical example that the API provides some useful information to see if we're on the last page. In this example, we know we're on the last page if the `next_page_url` JSON property on the body is null. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +After that, to apply the pagination, our API expects us to send a `X-Page` header with the current page on the paginator. We'll use the `$this->currentPage` property on the paginator as it acts like an index for the current iteration of the paginator. We will also make sure to send the `perPageLimit` to our API with the `X-Per-Page` header. This header is optional depending on the third-party API you are integrating with. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): Paginator
+{
+    return new class(connector: $this, request: $request) extends Paginator
+    {
+        protected ?int $perPageLimit = 100;
+
+        // ...
+    };
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +{% hint style="warning" %} +For this feature to work, you must implement sending the `perPageLimit` inside of your `applyPagination` method in whichever way your API may expect. +{% endhint %} + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/limit-offset-pagination.md b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/limit-offset-pagination.md new file mode 100644 index 0000000..c5d264c --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/limit-offset-pagination.md @@ -0,0 +1,141 @@ +# Limit/Offset Pagination + +First, you will want to import the `OffsetPaginator` class and return a new anonymous class that extends Saloon's `OffsetPaginator`. This class expects the connector and request to be passed in via the constructor arguments. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\OffsetPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): OffsetPaginator
+    {
+        return new class(connector: $this, request: $request) extends OffsetPaginator
+        {
+            //
+        };
+    }
+}
+
+ +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define a single property and two protected methods which are used to power the paginator. These properties/methods are: + +* **perPageLimit** - This property is required as this is the default limit of the paginator. Since this paginator requires limit/offset - the limit is always required. If you need to change the limit on a per-request basis you can change it on the paginator instance. +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here, you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next-page URLs, which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement the property and the two methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\OffsetPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): OffsetPaginator
+    {
+        return new class(connector: $this, request: $request) extends OffsetPaginator
+        {
+            protected ?int $perPageLimit = 100;
+        
+            protected function isLastPage(Response $response): bool
+            {
+                return $this->getOffset() >= (int)$response->json('total');
+            }
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+        };
+    }
+}
+
+ +First, we'll define a `perPageLimit` of 100. This means that every request will attempt to use a "limit" of 100. + +Next, let's assume in this hypothetical example that the API provides some useful information that helps us calculate if we're on the last page. For example, our API returns a `total` integer with every page - this number is simply the total results across all pages. We can use this to compare it with the current offset, and if the offset is greater than or equal to the total, we will stop. There are other ways of knowing if you are on the last page, so it's best to understand your API's pagination fully. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Changing the per-page limit on the paginator + +As mentioned previously, you must specify a "per-page limit" on your offset paginator. You may also use the `setPerPageLimit` method on an instantiated paginator if you want to change it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the OffsetPaginator** + +The OffsetPaginator will apply pagination by sending two **query parameters**: + +* limit +* offset + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects the "top" and a "skip" query parameters instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): OffsetPaginator
+{
+    return new class(connector: $this, request: $request) extends OffsetPaginator
+    {
+        protected ?int $perPageLimit = 100;
+    
+        protected function isLastPage(Response $response): bool
+        {
+            return $this->getOffset() >= (int)$response->json('total');
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            $request->query()->merge([
+                'top' => $this->perPageLimit,
+                'skip' => $this->getOffset(),
+            ]);
+    
+            return $request;
+        }
+    };
+}
+
+ +{% hint style="info" %} +The `getOffset()` method is a useful helper that calculates the current offset for you based on current interation and the per-page limit. +{% endhint %} + +### **Useful Methods/Properties On The OffsetPaginator** + +We previously mentioned that the `OffsetPaginator` class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **page** - An integer which will return the current page that the paginator is currently on. +* **getOffset()** - A helpful method that calculates the current offset for you based on current interation and the per-page limit. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/paged-pagination.md b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/paged-pagination.md new file mode 100644 index 0000000..0ba2ed9 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/pagination/paged-pagination.md @@ -0,0 +1,144 @@ +# Paged Pagination + +First, you will want to import the `PagedPaginator` class and return a new anonymous class that extends Saloon's `PagedPaginator`. This class expects the connector and request to be passed in via the constructor arguments. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\PagedPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): PagedPaginator
+    {
+        return new class(connector: $this, request: $request) extends PagedPaginator
+        {
+            //
+        };
+    }
+}
+
+ +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define two protected methods which are used to power the paginator. These methods are: + +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement these two methods on our paginator and dive into how it works. + +```php +json('next_page_url')); + } + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +Let's assume in this hypothetical example that the API provides some useful information to see if we're on the last page. In this example, we know we're on the last page if the `next_page_url` JSON property on the body is null. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): PagedPaginator
+{
+    return new class(connector: $this, request: $request) extends PagedPaginator
+    {
+        protected ?int $perPageLimit = 100;
+        
+        // ...
+    }
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the PagedPaginator** + +The PagedPaginator will apply pagination by sending two **query parameters**: + +* page +* per\_page + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects a "currentPage" and a "pageSize" instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): PagedPaginator
+{
+    return new class(connector: $this, request: $request) extends PagedPaginator
+    {
+        protected function isLastPage(Response $response): bool
+        {
+            return is_null($response->json('next_page_url'));
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            $request->query()->add('currentPage', $this->currentPage);
+    
+            if (isset($this->perPageLimit)) {
+                $request->query()->add('pageSize', $this->perPageLimit);
+            }
+    
+            return $request;
+        }
+    };
+}
+
+ +### **Useful Properties On The PagedPaginator** + +We previously mentioned that the PagedPaginator class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **currentPage** - An integer which will return the current page that the paginator is currently on. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/psr-support.md b/_docs/laravel-libs/saloon-docs/digging-deeper/psr-support.md new file mode 100644 index 0000000..368d9a4 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/psr-support.md @@ -0,0 +1,43 @@ +# ⛩️ PSR Support + +When you send a request, Saloon will construct a [PSR-7](https://www.php-fig.org/psr/psr-7/) request behind the scenes and pass it to the HTTP client. Saloon also uses [PSR-17](https://www.php-fig.org/psr/psr-17/) factories defined by the sender to create the URI (the full URL) and streams for the request body. When you make a request to Saloon, the response will contain a PSR-7 request and response pair. + +```php +send(new GetServersRequest); + +$psrResponse = $response->getPsrResponse(); +$psrRequest = $response->getPsrRequest(); +``` + +This design decision was made because the PSR-7 and 17 standards are very well-known and have been implemented by many popular HTTP clients. While Saloon uses Guzzle as the default way to send requests, if Guzzle suddenly becomes abandoned - Saloon can use one of many other HTTP clients without needing an entire rebuild from scratch. While Guzzle is amazing, and we'd never want it to go away - making Saloon independent of the HTTP client was a big step toward future-proofing the library. + +Another significant benefit to having PSR support is a better experience for you, the developer. With previous versions, Saloon heavily relied on Guzzle's config options to build the PSR-7 request internally, which meant that debugging was difficult because you never really knew what was sent to the third party. With version three, you can see the PSR request right before it is sent. If you want to learn more about debugging the PSR request, [click here](../the-basics/debugging.md). + +### Modifying the PSR-7 Request + +There may be a situation where you need to modify the PSR-7 request before it's sent to the HTTP client. You can use a special hook on either the connector or the request. This hook provides you with the built PSR-7 request that you can modify and return. To use this hook, extend the `handlePsrRequest` method on either your connector or request. + +If you use the method on the connector - the method will be run for every request sent through the connector. The method will give you access to both the PSR request and the Saloon `PendingRequest` if you need to use it for additional information, like the Saloon request class. + +```php +withHeader('X-API-Key', 'Howdy!'); + + return $request; + } +} +``` + +{% hint style="warning" %} +You may find it easier to modify the `Connector`, `Request`, or `PendingRequest` classes instead of the underlying PSR-7 request. You should be cautious when using this hook as there are many nicer, higher-level APIs in Saloon to modify the request. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/retrying-requests.md b/_docs/laravel-libs/saloon-docs/digging-deeper/retrying-requests.md new file mode 100644 index 0000000..e528376 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/retrying-requests.md @@ -0,0 +1,122 @@ +# 🎯 Retrying Requests + +Sometimes you may use APIs that are unreliable or require you to retry multiple times before a request is successful. Saloon has a global retry system that can be configured to automatically retry failed requests. + +### Configuring our connector + +Let's say that we have an API which isn't reliable. We can define a public `$tries` property on our connector which defines how many times a request will be sent if it fails. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+}
+
+ +Now when we send any request through this connector, if it fails it will be retried. + +```php +$forgeConnector = new ForgeConnector; + +$response = $forgeConnector->send(new UnreliableRequest); +``` + +If we get to attempt three and it still fails, Saloon will throw a `FatalRequestException` (for connection errors) or a `RequestException` for typical HTTP errors. + +{% hint style="warning" %} +The retry functionality will only work when sending requests synchronously. The retry logic will not work when using `sendAsync` or pools because Saloon needs to wait for a response to come back to determine if it needs to be retried. +{% endhint %} + +#### What does Saloon consider a failed request? + +By default, if the API couldn't be connected to or if the response status code is either a 4xx or 5xx, then Saloon will consider it a failed request. You can change this by extending the `hasRequestFailed` method on your connector. [Click here to learn more.](../the-basics/handling-failures.md#customising-when-saloon-thinks-a-request-has-failed) + +### Intervals + +You can also configure an interval in **milliseconds** that Saloon should wait between retries. You can configure an interval with the `$retryInterval` property. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?int $retryInterval = 1000;
+}
+
+ +#### Exponential Backoff + +You can also use exponential backoff when retrying which will double the retry interval after each unsuccessful attempt. This is useful as it can be less strenuous on the API if it is experiencing issues. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?int $retryInterval = 500;
+    
+    public ?bool $useExponentialBackoff = true;
+}
+
+ +### Exceptions + +By default, when all attempts have been exceeded, Saloon will either throw a `FatalRequestException` or a `RequestException`. You can choose to disable this behaviour and return the last response that Saloon received instead. + +If the exception was `FatalRequestException` then the exception will still be thrown as we wouldn't have a response to return. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?bool $throwOnMaxTries = false;
+}
+
+ +### Customising the request before the next retry + +In some situations, you might want to change the next request to improve the chances of the next retry being successful. You can overwrite the `handleRetry` method on the connector or request and use it to customise the `Request` class. You must also return a boolean in this method to tell Saloon if the retry should commence. + +
<?php
+
+use Saloon\Exceptions\RequestException;
+use Saloon\Http\Auth\TokenAuthenticator;
+use Saloon\Exceptions\FatalRequestException;
+use Saloon\Http\Request;
+    
+class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public function handleRetry(FatalRequestException|RequestException $exception, Request $request): bool
+    {
+        if ($exception instanceof RequestException && $exception->getResponse()->status() === 401) {
+            $request->authenticate(new TokenAuthenticator($this->getNewToken()));
+        }
+        
+        return true;
+    }
+}
+
+ +### Using the sendAndRetry method + +{% hint style="warning" %} +This method has been deprecated since Saloon v3.6.4 +{% endhint %} + +Saloon also has a `sendAndRetry` method which can be used on the fly on any connector or request without needing to configure anything. This method has the same functionality in the format of a method. + +```php +sendAndRetry( + request: new UnreliableRequest, + tries: 3, + interval: 500, + handleRetry: function (FatalRequestException|RequestException $exception, Request $request) { + // + }, + throw: true, + useExponentialBackoff: true, +); +``` diff --git a/_docs/laravel-libs/saloon-docs/digging-deeper/solo-requests.md b/_docs/laravel-libs/saloon-docs/digging-deeper/solo-requests.md new file mode 100644 index 0000000..6111731 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/digging-deeper/solo-requests.md @@ -0,0 +1,39 @@ +# ☝ Solo Requests + +While Saloon's typical setup of a connector and requests is great, sometimes all you need is to make a single request to a service. For scenarios like these, you may create a "SoloRequest" instead of making a connector and a single request. This saves you from having to create additional classes. + +### Setup + +Create a class, but instead of extending `Saloon\Http\Request`, you should extend `Saloon\Http\SoloRequest.` Next, just define everything else like you would a normal request. Make sure to include the full URL of the service you are integrating with. + +```php +send(); +``` diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/caching-responses.md b/_docs/laravel-libs/saloon-docs/installable-plugins/caching-responses.md new file mode 100644 index 0000000..dbc381a --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/caching-responses.md @@ -0,0 +1,211 @@ +# 🔁 Caching Responses + +There are scenarios where you may want to cache a response from an API, like retrieving a static list or retrieving data that you know won't change for a specified amount of time. Caching can be incredibly powerful and can speed up an application by relying less on a third-party integration. Saloon has a [first-party plugin](https://github.com/Sammyjo20/saloon-cache-plugin) that you can install to enable caching support. + +### Installation + +To install the caching functionality into Saloon, install the plugin using Composer. + +```bash +composer require saloonphp/cache-plugin "^3.0" +``` + +### Configuration + +Next, add the `Cacheable` interface and `HasCaching` trait to your request or connector. You must define the two methods. + +* resolveCacheDriver +* cacheExpiryInSeconds + +```php +send(new GetServersRequest); +$response->isCached(); // false + +// Next time it is sent... + +$response = $forge->send(new GetServersRequest); +$response->isCached(); // true +``` + +#### When will Saloon cache a request? + +Saloon will only cache a **successful** request when the method is either GET or OPTIONS. You can customise this by extending the `getCacheableMethods` method where you added the `HasCaching` trait. + +```php +invalidateCache(); + +$response = $forge->send($request); +``` + +### Temporarily Disabling Caching + +Sometimes you may wish to disable the caching on a per-request basis for debugging or to bypass caching. You can do this by using the `disableCaching` method on the request. + +```php +disableCaching(); + +$response = $forge->send($request); +``` + +### Source Code + +To view the source code of this plugin, [click here](https://github.com/Sammyjo20/saloon-cache-plugin). diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/handling-rate-limits.md b/_docs/laravel-libs/saloon-docs/installable-plugins/handling-rate-limits.md new file mode 100644 index 0000000..f2c9c66 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/handling-rate-limits.md @@ -0,0 +1,495 @@ +# ⛔ Rate Limit Handler + +Handling rate limits with API integrations can be hard. Saloon has a first-party plugin that provides you with the tools you need to prevent rate limits and handle what happens if a rate limit is exceeded. + +With this plugin, you are able to define various limits on a per-connector or request basis. You can also control if Saloon should throw an exception or sleep if a limit is reached. Saloon will keep track of how many requests are made and when a rate limit is hit, Saloon will prevent further requests on the connector/request until the rate limit has been lifted. + +Saloon will even listen out for "429 Too Many Requests" responses and will automatically throw exceptions before your future requests are sent and the limit will be lifted based on the `Retry-After` header. + +This plugin also comes with a Laravel Job middleware which you can use inside of your jobs to automatically release them back onto the queue if a rate limit has been reached. + +```php +everyMinute(), + Limit::allow(1000)->everyDay(), + Limit::allow(5000)->everyMonth(), + ]; + } + + protected function resolveRateLimitStore(): RateLimitStore + { + $redis = new Redis; + $redis->connect('127.0.0.1'); + + return new RedisStore($redis); + } +} + +``` + +### Installation + +You can install this plugin via Composer. + +``` +composer require saloonphp/rate-limit-plugin "^2.0" +``` + +### Getting Started + +To use the plugin, add the `HasRateLimit` trait to your connector or request. If you have a connector, you should put it on the connector, but it can be put on an individual request if a specific endpoint has a different rate limit or if you are using solo requests. If you are using the trait on both your connector and request, the rate limits are combined together. + +```php +use Saloon\Http\Connector; +use Saloon\RateLimitPlugin\Traits\HasRateLimits; + +class SpotifyConnector extends Connector +{ + use HasRateLimits; +} +``` + +Next, you will be required to implement two methods: `resolveLimits` and `resolveRateLimitStore`. These methods allow you to define the limits that Saloon will keep track of and the store where the limit "hits" will be kept. + +```php +use Saloon\Http\Connector; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\MemoryStore; +use Saloon\RateLimitPlugin\Traits\HasRateLimits; + +class SpotifyConnector extends Connector +{ + use HasRateLimits; + + protected function resolveLimits(): array + { + return []; + } + + protected function resolveRateLimitStore(): RateLimitStore + { + return new MemoryStore; + } +} +``` + +### Stores + +Here are the various stores that the rate-limiting plugin supports. You may also [create your own stores](https://github.com/Sammyjo20/saloon-docs/blob/v2/digging-deeper/broken-reference/README.md) if this library does not come with the one you need. Stores are used to keep track of how many requests have been sent through a given connector/request. + +#### Available Stores + +* In-Memory (Array) +* File +* Redis +* Predis +* PSR Cache Store +* Laravel Cache Store + +#### Memory Store + +The simplest store. This store is persisted on the current instance of the connector/request and all information is lost when the connector is destructed. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\MemoryStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new MemoryStore; +} +``` + +#### File Store + +This store will use the local filesystem to store the limits. The only requirement for this store is for you to define the absolute path to a directory where you would like the limits to be stored. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\FileStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new FileStore('some/application/directory'); +} +``` + +#### Redis Store + +This store will use PHP's `Redis` extension to store the limits on a Redis database. You should pass the Redis configuration into this store. + +```php +use Redis; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\RedisStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + $client = new Redis; + $client->connect('127.0.0.1'); + + return new RedisStore($client); +} +``` + +#### Predis Store + +Similar to the `RedisStore`, the `PredisStore` allows you to connect to Redis through the `predis/predis` PHP library. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\PredisStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + $client = new Predis\Client([ + 'scheme' => 'tcp', + 'host' => '10.0.0.1', + 'port' => 6379, + ]); + + return new PredisStore($client); +} +``` + +#### PSR Cache Store + +This store supports any PSR-16 cache store provided by the `psr/simple-cache` library. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\PsrStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new PsrStore(new SomePsr16Store); +} +``` + +#### Laravel Cache Store + +This store can only be used in a Laravel environment but allows you to use any of Laravel's cache disks. + +```php +use Illuminate\Support\Facades\Cache; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\LaravelCacheStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new LaravelCacheStore(Cache::store('redis')); +} +``` + +### Limits + +While this plugin can detect if a 429 status occurs from a response, it's better to prevent your application from hitting rate limits than let them happen. This plugin provides an expressive `Limit` class which can be used to define different limits. You can define as many limits as you like, with various intervals. + +#### What limit type should I be using? + +The rate limit plugin supports two types of limits, time-based limiters, for example 100 requests every 60 seconds and a "Leaky Bucket" limiter. Please continue reading if you need to use time-based limiters or you can [click here for leaky bucket limiters](handling-rate-limits.md#leaky-bucket-limiter). + +#### Configuring Limits + +Here is a simple example of a limit for an API which only allows 60 requests per minute, but has a daily limit of 1,000 API calls. There are many different limit intervals, as well as different ways you can instruct Saloon to handle the limit. There is no restriction on the number of limits you can have. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->everyMinute(), + Limit::allow(1000)->everyDay(), + ]; +} +``` + +#### Limit Intervals + +There are various limit intervals which you can use on your limiter, ranging for seconds to up to the end of the month. + +```php +use Saloon\RateLimitPlugin\Limit; + +Limit::allow(60)->everySeconds(seconds: 5); +Limit::allow(60)->everyMinute(); +Limit::allow(60)->untilEndOfMinute(); +Limit::allow(60)->everyFiveMinutes(); +Limit::allow(60)->everyThirtyMinutes(); +Limit::allow(60)->everyHour(); +Limit::allow(60)->untilEndOfHour(); +Limit::allow(60)->everySixHours(); +Limit::allow(60)->everyTwelveHours(); +Limit::allow(60)->everyDay(); +Limit::allow(60)->everyDayUntil('8pm'); +Limit::allow(60)->untilMidnightTonight(); +Limit::allow(60)->untilEndOfMonth(); +``` + +#### Custom Names + +Sometimes you may need to add a name to your limiter. A good example of this is if you have separate API keys per user and therefore require a different API rate limit per user. You can add the `name()` method to your limit to specify a custom name for your limiter. Each limiter's name must be unique. + +```php +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->everyMinute()->name('spotify-limit-user-' . $this->userId), + ]; +} +``` + +#### Custom Prefixes + +Saloon will append the class name of the connector or a request as the prefix to the limiter name. For example SpotifyConnector:30\_every\_60. You may customise the prefix by extending the `getLimiterPrefix` method on your connector or request. + +```php +protected function getLimiterPrefix(): ?string +{ + return 'spotify-user-' . $this->userId; +} +``` + +#### Custom Thresholds + +You may want to specify the percentage threshold that Saloon should accept as the number of "hits" on a given limit. This is useful if you want to stay just under the real API limit while still defining the limit in the connector/request. + +The threshold must be a number between 0 and 1 (e.g 0.8 = 80%) + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60, threshold: 0.8)->everyMinute(), // Will fail when at 80% capacity + ]; +} +``` + +#### Sleep + +If would rather Saloon didn't throw an exception, you can use the `sleep` method when defining a limit. When using the sleep method, an exception won't be thrown. Instead, Saloon will wait the remaining number of seconds before a request is attempted again. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->sleep(), + ]; +} +``` + +#### "429: Too Many Attempts" Detection + +While it's recommended that you should define your limits above, Saloon will try to catch 429 "Too Many Attempts" errors from an API and will automatically mark a limit as "exceeded" if it sees this status. By default, Saloon will attempt to parse the `Retry-After` header to work out when a limit has been exceeded. If Saloon cannot calculate this, the limit will be released after 60 seconds. + +You can customise this behaviour by overwriting the `handleTooManyAttempts` method. + +```php +protected function handleTooManyAttempts(Response $response, Limit $limit): void +{ + if ($response->status() !== 429) { + return; + } + + $limit->exceeded( + releaseInSeconds: RetryAfterHelper::parse($response->header('Retry-After')), + ); +} +``` + +Alternatively, you may choose to disable this functionality. You can do this by setting the `detectTooManyAttempts` property to `false` in your connector/request's constructor. + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Stores\MemoryStore;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    public function __construct()
+    {
+        $this->detectTooManyAttempts = false;
+    }
+}
+
+ +When Saloon detects a rate limit has been exceeded, Saloon will throw a `RateLimitReachedException` . If you would like your application to sleep instead of throwing an exception you can extend the `getTooManyAttemptsLimiter` method and apply the `sleep` modifier + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Stores\MemoryStore;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    protected function getTooManyAttemptsLimiter(): ?Limit
+    {
+        return Limit::custom($this->handleTooManyAttempts(...))->sleep();
+    }
+}
+
+ +{% hint style="warning" %} +When using the `sleep` modifier, Saloon will automatically attempt to make another request after detecting a rate limit being reached in the response. This does not affect the retry definition you may have defined on your connector or request. +{% endhint %} + +### Leaky Bucket Limiter + +Some applications may implement a "Leaky Bucket" algorithm for their rate limits, essentially this means that while you are making requests, within a given time frame (usually every second) you "gain" additional requests you can make. For example if an API integration allowed 60 requests per minute but had a leak rate of 1 per second, you could in theory be constantly communicating with the API as long as you stay within the 60 request limit. + +The plugin implementation is really straight forward. In order to implement the above example you would write something like this. + +```php +use Saloon\RateLimitPlugin\Bucket; + +protected function resolveLimits(): array +{ + return [ + Bucket::capacity(60) + ->leak(1) + ->everySeconds(1) + ->sleep() + ]; +} +``` + +{% hint style="info" %} +The `Bucket` class extends the `Limit` class so you may use all of the limit intervals as defined above. +{% endhint %} + +You'll notice that it does an initial burst of 60 requests, then the bucket fills back up and the next second does 1 request, then the next second does 1 request, which adheres to our "leak 1 every 1 second" specification. + +### Handling Rate Limits Being Exceeded + +When a rate limit has been reached, Saloon will throw a `RateLimitReachedException`. This exception contains a `getLimit` method which may be used to see the limit that has thrown the exception and see the number of seconds to wait before a request can be sent again. This can be done with a simple try-catch approach or if you are using the provided Laravel job middleware, then you can instruct your jobs to wait until the limit has been lifted. + +#### Try/Catch + +As mentioned above, Saloon will throw an exception if a rate limit is reached or if the API returns a 429: Too Many Requests response. You could use a try/catch block to catch the exception and do something with the limit. For example, you may return an error to your users to let them know how long they need to wait - or you might retry the request later. If you are using Saloon in a context of a queued process, then you may want to retry the queued job in the future, from the remaining seconds. + +```php +use Saloon\RateLimitPlugin\Exceptions\RateLimitReachedException; + +$spotify = new SpotifyConnector; + +try { + $response = $spotify->send(new GetPlaylistRequest); +} catch (RateLimitReachedException $exception) { + $seconds = $exception->getLimit()->getRemainingSeconds(); + + // Return our users back to our application with a custom response that could be + // shown on the front end. + + return response("Too many requests to Spotify's API. Please try again in ${$seconds} seconds."); +} +``` + +#### Sleep + +If would rather Saloon didn't throw an exception, you can use the `sleep` method when defining a limit. When using the sleep method, an exception won't be thrown. Instead, Saloon will wait the remaining number of seconds before a request is attempted again. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->sleep(), + ]; +} +``` + +#### Laravel Job Middleware + +If you are using Laravel, then this library comes with a [job middleware](https://laravel.com/docs/queues#job-middleware) that you can use. This job middleware will catch the `RateLimitReachedException` and automatically release your job back onto the queue with the remaining seconds added. Add this to the `middleware` method on your Laravel Job. + +```php +use Saloon\RateLimitPlugin\Helpers\ApiRateLimited; + +public function middleware(): array +{ + return [new ApiRateLimited]; +} +``` + +{% hint style="info" %} +You may also wish to increase your job's tries when using this middleware in case the job needs to be retried multiple times. +{% endhint %} + +### Creating your own store + +You may create your own rate limit store by implementing the `RateLimitStore` interface. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; + +class CustomStore implements RateLimitStore +{ + /** + * Get a rate limit from the store + */ + public function get(string $key): ?string + { + // + } + + /** + * Set the rate limit in the store + */ + public function set(string $key, string $value, int $ttl): bool + { + // + } +} +``` + +### Disabling Rate Limiting + +Sometimes you might want to disable rate limiting by default or even disable it on a per-connector basis. You can either use a property to disable the rate-limiting functionality by default, or you can use the `useRateLimitPlugin()` method to disable it on a per-instance basis. + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    public function __construct()
+    {
+        $this->rateLimitingEnabled = false;
+    }
+}
+
+// Or...
+
+$connector = new SpotifyConnector;
+$connector->useRateLimitPlugin(false);
+
diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/laravel-integration.md b/_docs/laravel-libs/saloon-docs/installable-plugins/laravel-integration.md new file mode 100644 index 0000000..60952d8 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/laravel-integration.md @@ -0,0 +1,69 @@ +# ⛵ Laravel Plugin + +Saloon has been built to integrate beautifully with [Laravel](https://laravel.com). The separate Laravel plugin comes with a facade that helps with mocking and recording requests, Artisan console commands to easily build your API integrations, and events which you can listen to and build further functionality from. + +### Installation + +You can install the separate package with Composer. You must already have`saloonphp/saloon` as a required dependency in your `composer.json` file. + +```bash +composer require saloonphp/laravel-plugin "^3.0" +``` + +Next, publish the configuration file with the following Artisan command + +```bash +php artisan vendor:publish --tag=saloon-config +``` + +### Artisan Console Commands + +The Laravel plugin provides a few useful Artisan commands that can help you build your API integrations. + +
CommandDescription
php artisan saloon:connectorCreates a new connector - You can provide an optional --oauth option if you would like to create an OAuth2 connector.
php artisan saloon:requestCreates a new request
php artisan saloon:responseCreates a custom response
php artisan saloon:pluginCreates a plugin
php artisan saloon:authCreates a custom authenticator
php artisan saloon:listList all your API integrations
+ +### Saloon Facade + +The Laravel plugin also provides a facade which can be used to feel more unified with the rest of Laravel. You can use the Facade in tests instead of the `MockClient::global()` method. + +```php +use Saloon\Laravel\Facades\Saloon; + +Saloon::fake([ + GetServersRequest::class => MockResponse::make(body: '', status: 200), +]); +``` + +To learn more about testing API integrations, [click here](../the-basics/testing/). + +### Laravel Nightwatch Support + +From v3.6.0 the Saloon Laravel plugin natively supports Laravel Nightwatch. The plugin will automatically register a Nightwatch middleware on all of your connectors. + +### Laravel Telescope Support + +From v3.8.0 the Saloon Laravel plugin natively supports Laravel Telescope. The plugin will automatically register a Telescope middleware on all of your connectors. + +### Events + +With the Laravel plugin installed, Saloon will start sending events when requests are being sent. These events are: + +* SendingSaloonRequest +* SentSaloonRequest + +These events can be added to your `EventServiceProvider` and you can create listeners to handle when these happen. + +### Laravel Zero + +If you are using [Laravel Zero](https://github.com/laravel-zero/laravel-zero), the `SaloonServiceProvider` that registers the `Saloon` facade as well as some default middleware might not be registered. You can register Saloon's service provider in your `AppServiceProvider.php`'s `register()` method definition. + +```php +app->register(SaloonServiceProvider::class); +} +``` diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/lawman.md b/_docs/laravel-libs/saloon-docs/installable-plugins/lawman.md new file mode 100644 index 0000000..c30433e --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/lawman.md @@ -0,0 +1,178 @@ +# 🤠 Lawman + +Lawman is a [PestPHP](https://pestphp.com/) Plugin for SaloonPHP which allows you to easily write architecture tests for your API integrations with a focus on them being easy to write and easy to read. After all, if SaloonPHP makes our API integrations beautiful, the tests for them should be beautiful too, right? + +Lawman is a third-party plugin written and maintained by [Jon Purvis](https://twitter.com/JonPurvis\_) and gives you access to Expectations for your Connectors, Requests, Plugins and more, to ensure they stick to whichever architecture rules your application has. + +One of the great things about Lawman is because it's a Pest plugin, it will work with regular PestPHP Expectations, just chain them up and you're good to go! + +### Installation + +You can install the plugin using Composer. If you run the following command, it will install it as a dev dependency: + +```bash +composer require jonpurvis/lawman --dev +``` + +Lawman makes use of autoloading with Composer, so once you've installed the package, the Expectations should appear as you type! + +### Examples + +Let's take a look at how you can use Lawman to easily write Arch tests for your API Integrations. + +Let's say we have a Connector class that we want to test, with PestPHP we could do the following: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toExtend('Saloon\Http\Connector') + ->toUse('Saloon\Traits\Plugins\AcceptsJson') + ->toUse('Saloon\Traits\Plugins\AlwaysThrowOnErrors'); +``` + +So that test is ensuring our class extends the base Connector and uses the `AcceptJson` and `AlwaysThrowOnErrors` traits. Whilst that test works, we could perhaps make it quicker to write and easier to read, so with Lawman, you can do: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toUseAcceptsJsonTrait() + ->toUseAlwaysThrowOnErrorsTrait(); +``` + +Next up, let's take a Request test that we have: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toExtend('\Saloon\Http\Request') + ->toImplement('Saloon\Contracts\Body\HasBody') + ->toUse('Saloon\Traits\Body\HasFormBody') + ->toUse('Saloon\Traits\Plugins\AcceptsJson'); +``` + +Lawman makes this test much nicer to read: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toBeSaloonRequest() + ->toSendPostRequest() + ->toHaveFormBody() + ->toUseAcceptsJsonTrait(); +``` + +What about if we want to test our Connector has an Authentication method? Lawman makes this easy to do, it even works with multi auth: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toUseCertificateAuthentication() + ->toUseTokenAuthentication(); +``` + +Lawman also has Expectations for the Pagination, Cache and Rate Limit Plugins: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toBeSaloonRequest() + ->toSendPostRequest() + ->toUsePagedPagination() + ->toHaveCaching() + ->toHaveRateLimits() +``` + +Maybe our Connector has some Retry instructions that we want to test. Again, with Lawman, it's as simple as: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toBeTriedAgainOnFailure() + ->toHaveRetryInterval() + ->toUseExponentialBackoff() +``` + +### Available Expectations + +#### Authentication + +* `toUseTokenAuthentication` +* `toUseBasicAuthentication` +* `toUseCertificateAuthentication` +* `toUseHeaderAuthentication` + +#### Cache + +* `toHaveCaching` + +#### Connector + +* `toBeSaloonConnector` + +#### Pagination + +* `toUsePagedPagination` +* `toUseOffsetPagination` +* `toUseCursorPagination` +* `toUseCustomPagination` + +#### Properties + +* `toSetConnectTimeout` +* `toSetRequestTimeout` +* `toBeTriedAgainOnFailure` +* `toHaveRetryInterval` +* `toUseExponentialBackoff` +* `toThrowOnMaxTries` + +#### Rate Limit + +* `toHaveRateLimits` + +#### Request + +* `toBeSaloonRequest` +* `toHaveRequestMethod` +* `toSendGetRequest` +* `toSendPostRequest` +* `toSendHeadRequest` +* `toSendPutRequest` +* `toSendPatchRequest` +* `toSendDeleteRequest` +* `toSendOptionsRequest` +* `toSendConnectRequest` +* `toSendTraceRequest` +* `toHaveJsonBody` +* `toHaveMultipartBody` +* `toHaveXmlBody` +* `toHaveFormBody` +* `toHaveStringBody` +* `toHaveStreamBody` + +#### Response + +* `toBeSaloonResponse` + +#### Trait + +* `toUseAcceptsJsonTrait` +* `toUseAlwaysThrowOnErrorsTrait` +* `toUseTimeoutTrait` +* `toUseAuthorisationCodeGrantTrait` +* `toUseClientCredentialsGrantTrait` + +### Contributing + +Contributions to Lawman are welcome! If you can think of an Expectation that would be useful for others to utilise in their tests, please submit a PR on GitHub. The only real rules are: + +* All Expectations must have a test to cover it +* A new Fixture class should be added for every new Expectation + +If you just follow how previous Expectations are done, then you should be good. + +### Reporting an Issue + +If you do spot an issue with Lawman, please [open an issue](https://github.com/JonPurvis/lawman/issues) on GitHub. diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/sdk-generator.md b/_docs/laravel-libs/saloon-docs/installable-plugins/sdk-generator.md new file mode 100644 index 0000000..25e9080 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/sdk-generator.md @@ -0,0 +1,57 @@ +# 🏭 SDK Generator + +The Saloon SDK Generator is a third-party Saloon plugin written and maintained by [Crescat](https://crescat.io/) ([Helge Sverre](https://twitter.com/HelgeSverre)) and allows people to easily generate Saloon SDKs from an OpenAPI file or Postman collection. The generator can automatically create connectors, requests and responses for you to help save you time when starting a new SDK. + +{% hint style="info" %} +Note: This tool helps you set up the foundation for your SDK, but it might not create a complete, ready-to-use solution. +{% endhint %} + +
+ +### Installation + +You can install the Saloon SDK Generator through Composer. You can install it globally on your machine and have a simple CLI to generate SDKs. + +```sh +composer global require crescat-io/saloon-sdk-generator +``` + +{% hint style="info" %} +The library requires PHP 8.1 and above +{% endhint %} + +### Basic Usage + +To generate the PHP SDK from an API specification file, run the following command: + +```sh +sdkgenerator generate:sdk API_SPEC_FILE.{json|yaml|yml} + --type={postman|openapi} + [--name=SDK_NAME] + [--output=OUTPUT_PATH] + [--namespace=Company\\Integration] + [--force] + [--dry] + [--zip] +``` + +Replace the placeholders with the appropriate values: + +* `API_SPEC_FILE`: Path to the API specification file (JSON or YAML format). +* `--type`: Specify the type of API specification (`postman` or `openapi`). +* `--name`: (Optional) Specify the name of the generated SDK (default: Unnamed). +* `--namespace`: (Optional) Specify the root namespace for the SDK (default: `App\\Sdk`). +* `--output`: (Optional) Specify the output path where the generated code will be created (default: ./Generated). +* `--force`: (Optional) Force overwriting existing files. +* `--dry`: (Optional) Perform a dry run. It will not save generated files, only show a list of them. +* `--zip`: (Optional) Use this flag to generate a zip archive containing all the generated files. + +### Full Documentation + +The full documentation can be found by visiting the Github repository here: + +{% embed url="https://github.com/crescat-io/saloon-sdk-generator" %} + +### Issue Tracking + +As this is not directly affiliated with Saloon, please report any issues you have directly on the repository linked above. diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/traits.md b/_docs/laravel-libs/saloon-docs/installable-plugins/traits.md new file mode 100644 index 0000000..5efbe45 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/traits.md @@ -0,0 +1,48 @@ +# 🏗 Building Your Own Plugins + +Saloon has plugins which make it easy for you to add logic to your connector or requests in a reusable and elegant way. Plugins are traits that can be added to either a request or a connector and have a special "boot" method which is invoked during the request lifecycle. + +### Getting Started + +It's easy to create your own plugin for Saloon, just create a trait and add it to either your connector or request. In this example, we will create a logging plugin that when added will log the request being sent to [Ray](https://myray.app/). + +Our plugin will be called `HasLogging` . In order for Saloon to execute this plugin, we must create a public method that starts with `boot` followed by the name of the trait. For example: `bootHasLogging`. The method is given an instance of `PendingRequest`. + +{% tabs %} +{% tab title="Definition (Trait)" %} +
<?php
+
+trait HasLogging
+{
+    public function bootHasLogging(PendingRequest $pendingRequest): void
+    {
+        ray($pendingRequest);
+    }
+}
+
+ +{% hint style="warning" %} +You must not use `$this` inside of the trait, as mutating the original request or connector is discouraged. The PendingRequest is the source of truth while a request is being sent. +{% endhint %} +{% endtab %} + +{% tab title="Usage (Connector)" %} +
<?php
+
+class ForgeConnector extends Connector
+{
+    use HasLogging;
+}
+
+{% endtab %} +{% endtabs %} + +When you send your request, plugins are the first things that are invoked, even before the `boot` method. This is to allow maximum compatibility with [middleware ](../digging-deeper/middleware.md)and [authenticators](../the-basics/authentication.md). This also means that because it's the first process in the chain, other steps like middleware and the boot method will be able to overwrite anything added by a plugin. + +
+ +Because we added the trait to our connector, every request will use the `HasLogging` plugin. If you would like the plugin to be applied to just one request, you can add the plugin to the request only. + +{% hint style="warning" %} +Take caution when adding the plugin to both the connector and the request, because the plugin will be executed twice. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/installable-plugins/xml-wrangler.md b/_docs/laravel-libs/saloon-docs/installable-plugins/xml-wrangler.md new file mode 100644 index 0000000..0e232ae --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/installable-plugins/xml-wrangler.md @@ -0,0 +1,121 @@ +# 🏇 XML Wrangler + +XML Wrangler is a first-party library written by the maintainer of Saloon and is designed to modernise reading and writing XML in PHP. XML Wrangler can detect errors in XML, read gigabytes of XML files and convert XML results into Laravel Collections. Its powerful reader supports dot notation and XPath queries. + +### Key Features + +* Convert XML into an array +* Write XML from an array +* Memory-safe reader for large XML documents +* Dot notation and XPath support for reading + +{% tabs %} +{% tab title="Reader" %} +```php +use Saloon\XmlWrangler\XmlReader; + +$reader = XmlReader::fromString($xml); + +// Convert XML to an array + +$reader->values(); // ['breakfast_menu' => [['name' => '...'], ['name' => '...'], ['name' => '...']] + +// Query the XML + +$reader->value('food.0')->sole(); // ['name' => 'Belgian Waffles', 'price' => '$5.95', ...] + +$reader->xpathValue('//food[@bestSeller="true"]/name')->get(); // ['Belgian Waffles', 'Berry-Berry Belgian Waffles'] + +$reader->element('food.0')->sole()->getAttributes(); // ['soldOut' => false, 'bestSeller' => true] +``` +{% endtab %} + +{% tab title="XML" %} +```xml + + + Belgian Waffles + $5.95 + Two of our famous Belgian Waffles with plenty of real maple syrup + 650 + + + Strawberry Belgian Waffles + $7.95 + Light Belgian waffles covered with strawberries and whipped cream + 900 + + + Berry-Berry Belgian Waffles + $8.95 + Light Belgian waffles covered with an assortment of fresh berries and whipped cream + 900 + + +``` +{% endtab %} +{% endtabs %} + +### Documentation + +Click the card below to read the documentation + +{% embed url="https://github.com/saloonphp/xml-wrangler" %} + +### Saloon Integration + +XML Wrangler is also integrated with Saloon! Once installed, you'll be able to use the `xmlReader()` method on your responses to instantiate an XML Wrangler reader. + +```php +$response = $connector->send($request); + +$reader = $response->xmlReader(); + +// $reader->values(); +// etc... +``` + +#### Request Body + +You may also choose to use XML Wrangler to create the request body when sending XML requests in Saloon. + +```php +write('root', [ + 'ubuntu-version' => $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]); + + // Same as... + + // + // + // ubuntuVersion + // type + // provider + // + } +} +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/authentication.md b/_docs/laravel-libs/saloon-docs/the-basics/authentication.md new file mode 100644 index 0000000..058fb25 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/authentication.md @@ -0,0 +1,189 @@ +# 🔐 Authentication + +Saloon has optional authenticator classes to help you with the most common types of authentication. These are classes that can be used on your connector or request. + +[You can view all of the built-in authenticators on GitHub.](https://github.com/saloonphp/saloon/tree/v3/src/Http/Auth) + +### Authorization "Bearer" Tokens + +The `TokenAuthenticator` class can be used to add a `Authorization: Bearer` header to the request. Just extend the `defaultAuth` method and return the authenticator class. + +```php +token); + } +} +``` + +### Basic Auth (Base64 Encoded) + +The `BasicAuthenticator` class can be used to add a `Authorization: Basic` header to the request. Just extend the `defaultAuth` method and return the authenticator class. + +```php +username, $this->password); + } +} +``` + +### Query Parameter + +The `QueryAuthenticator` class can be used to add a query parameter to requests. Just extend the `defaultAuth` method and return the authenticator class. + +```php +token); + } +} +``` + +### Certificate Auth + +The `CertificateAuthenticator` class can be used to authenticate with a custom client-side certificate. An optional password can be provided. Just extend the `defaultAuth` method and return the authenticator class. + +```php +path, $this->password); + } +} +``` + +### Header Auth + +The `HeaderAuthenticator` class can be used to authenticate with a custom header. Just extend the `defaultAuth` method and return the authenticator class. + +```php +token, 'X-API-KEY'); + } +} +``` + +### Multiple Authenticators + +You may need to use multiple authenticator classes together, like a certificate and an authorization token. You can use the `MultiAuthenticator` class for this scenario. + +```php +certificate), + new TokenAuthenticator($this->token), + ); + } +} +``` + +### Custom Authentication + +If your API integration requires a more complicated authentication process, you can create your own authenticator classes which can be used on your connector. This helps abstract any complicated logic away from the connector keeping it tidy. + +```php +headers()->add(...); + // $pendingRequest->config()->add(...); + } +} +``` + +```php +token); + } +} +``` + +### The authenticate method + +You may also use the `authenticate` method on your connector or request if you would like to use or overwrite an authenticator at runtime. + +```php +$forge = new ForgeConnector; + +$forge->authenticate(new TokenAuthenticator($user->forge_token)); + +// $forge->send(...) +``` + +{% hint style="info" %} +Only one authenticator can be used at the same time. +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/the-basics/building-sdks.md b/_docs/laravel-libs/saloon-docs/the-basics/building-sdks.md new file mode 100644 index 0000000..c49a1a2 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/building-sdks.md @@ -0,0 +1,184 @@ +# ✨ Building SDKs + +Saloon provides everything you need to build a great SDK or library for an API. It already offers the ability to mock responses, provide authentication, implement OAuth2 boilerplate and even record your API requests in your tests. With Saloon you won't need to write the same boilerplate code over and over again. Saloon comes with just three dependencies making your library or SDK lightweight. + +{% hint style="info" %} +You can see some Saloon SDKs built by the PHP community by [visiting the showcase page!](../conclusion/showcase.md) +{% endhint %} + +### Getting Started + +This guide will be using PokéAPI as an example API. [Click here to see a full SDK example repository](https://github.com/Sammyjo20/pokeapi-sdk/tree/v3). This guide assumes you know the basics of connectors, requests and sending requests. + +To start building an SDK with Saloon, we recommend that you create a connector as your SDK class. This class allows you to configure the base URL and any defaults you may need like default headers or authentication. + +#### Example SDK Connector + +This is an example SDK for the [PokéAPI](https://pokeapi.co/). As you can see, I have defined the API base URL, as well as used the constructor to provide an authentication token. I have also defined some default headers. + +```php + 'application/json', + 'Content-Type' => 'application/json', + ]; + } + + protected function defaultAuth(): TokenAuthenticator + { + return new TokenAuthenticator($this->token); + } +} +``` + +Now that we have created the SDK class, all we need to do is instantiate it and provide the API token. We are now ready to send requests through our SDK. You may add your methods to this class as it is the root class of your SDK. + +```php +send($request); +``` + +With this method, it’s really simple to build your SDK. All you would need to do is create all the requests and then document them in your README. Developers using your SDK can just instantiate your SDK and then use the `send` methods. This also gives the developer freedom to customise the request's headers, config and query parameters if they choose to. + +### Sending Requests With Methods + +Sometimes you may want to make it easy for the developer to find all the methods that they need to call the API through your SDK. You can create methods on your connector which send an API request or you could write a "resource" class that contains lots of requests + +{% tabs %} +{% tab title="Definition" %} +```php +class Pokeapi extends Connector +{ + // ... + + public function allPokemon(int $page): Response + { + return $this->send(new GetAllPokemon($page)); + } +} +``` +{% endtab %} + +{% tab title="Usage" %} +```php +allPokemon(page: 1); +``` +{% endtab %} +{% endtabs %} + +### Request Resources/Groups + +The resource pattern can help you combine your SDK requests into simple groups that are easy for the developer to find and consume. First, we'll create a class that extends Saloon's `BaseResource` class. + +For this API, I will create a Pokémon resource which will group all the Pokémon requests together. Imagine a resource like a controller in an MVC framework like Laravel. You should pass any arguments the request needs through the method arguments. + +
<?php
+
+use Saloon\Http\BaseResource;
+use Saloon\Http\Response;
+
+class PokemonResource extends BaseResource
+{
+     public function all(int $page): Response
+     {
+         return $this->connector->send(new GetAllPokemon($page));
+     }
+     
+     public function get(int $id): Response
+     {
+         return $this->connector->send(new GetSinglePokemon($id));
+     }
+}
+
+ +#### Defining a resource on your connector + +Now we'll define a method on the connector which returns this resource class. Don't forget to pass the connector's instance (`$this`) into the resource. + +```php +class Pokeapi extends Connector +{ + // ... + + public function pokemon(): PokemonResource + { + return new PokemonResource($this); + } +} +``` + +Now all our users have to do is access the `pokemon()` method on the SDK class to get access to all the various requests that our SDK has to offer. + +```php +pokemon()->all(page: 1); + +$giratina = $pokeapi->pokemon()->get(id: 'giratina'); +``` + +### Custom Responses + +You may wish to customise the `Response` class that is returned by Saloon from your SDK connector. [Click here to read more about custom responses.](responses.md#custom-responses) + +### Additional Features + +Please read through the other sections of Saloon's documentation to see the other features that you can offer for your SDK. Every other feature like testing, authentication, failure handling is all supported for SDKs. + +### Testing + +When building an SDK, it's important to write tests that ensure the SDK calls the correct requests from an API and returns the right response, especially if you're converting the response into a data-transfer-object. [Read through the testing section of the documentation](building-sdks.md#testing) to get familiar with mocking and recording requests. diff --git a/_docs/laravel-libs/saloon-docs/the-basics/connectors.md b/_docs/laravel-libs/saloon-docs/the-basics/connectors.md new file mode 100644 index 0000000..c6c47ff --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/connectors.md @@ -0,0 +1,118 @@ +# 🔌 Connectors + +Connectors are classes which define an API integration's properties like its URL and headers. Any behaviour that should be used on every request like authentication should be defined in a connector. You should have a separate connector for each API integration. + +### Getting Started + +You should establish a standard place to keep your API connectors. For example in Laravel, a sensible place would be to place them inside the `App/Http/Integrations`folder. + +Create a new class and extend the abstract `Connector` class. You will then need to define a method `resolveBaseUrl`. This is the URL that points to the API. + +```php + If you have installed the Laravel plugin, you can use the **php artisan saloon:connector** command to create a connector. + +### Headers + +Most API integrations will have common headers used by all of its requests. You can extend the `defaultHeaders` method to define the headers. + +
class ForgeConnector extends Connector
+{
+    // ...
+
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ];
+    }
+}
+
+ +You can also use the `headers` method on a connector instance. + +```php +$forge = new ForgeConnector; + +$forge->headers()->add('Content-Type', 'text/plain'); +``` + +### Timeout + +By default, Saloon will have a connection timeout of 10 seconds and a request timeout of 30 seconds. You can customise this by using the `HasTimeout` trait and specifying a `connectTimeout` and `requestTimeout` property. + +```php +use Saloon\Traits\Plugins\HasTimeout; + +class ForgeConnector extends Connector +{ + use HasTimeout; + + protected int $connectTimeout = 60; + + protected int $requestTimeout = 120; +} +``` + +### Constructor Arguments + +Since connectors are just classes, you can define a constructor to populate its default properties. For example, if the URL changes per user of your application you can define this as a constructor argument. + +```php +class ForgeConnector extends Connector +{ + public function __construct(protected readonly string $baseUrl) { + // + } + + public function resolveBaseUrl(): string + { + return $this->baseUrl; + } +} +``` + +```php +$connector = new ForgeConnector('https://forge.laravel.com/api/v1'); +``` + +### HTTP Client Config + +The connector uses a HTTP client to send the request. By default, this client is [Guzzle](https://github.com/guzzle/guzzle). If you would like to define Guzzle config options then you can extend the `defaultConfig` method. + +[Click here to see a list of the available options Guzzle provide.](https://docs.guzzlephp.org/en/stable/request-options.html) + +```php +class ForgeConnector extends Connector +{ + // ... + + public function defaultConfig(): array + { + return [ + 'stream' => true, + ]; + } +} +``` + +You can also use the `config` method on a connector instance. + +```php +$forge = new ForgeConnector; + +$forge->config()->add('stream', true); +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/data-transfer-objects.md b/_docs/laravel-libs/saloon-docs/the-basics/data-transfer-objects.md new file mode 100644 index 0000000..842efa9 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/data-transfer-objects.md @@ -0,0 +1,185 @@ +# 🛸 Data Transfer Objects + +When building API integrations, sometimes dealing with a raw response or a JSON response can be tedious and unpredictable. Data transfer objects are a good solution as they allow you to define a structure for a request and response. Saloon supports casting a response from an API request into a DTO. + +### Defining DTOs from responses + +In your request, extend the `createDtoFromResponse` method. Within this method, you get access to the `Response` object containing the response to cast into a data transfer object. + +```php +json(); + + return new Server( + id: $data['id'], + name: $data['name'], + ipAddress: $data['ip'], + ); + } +} +``` + +This is what the `Server` DTO looks like: + +```php +send(new GetServerRequest(id: 12345)); + +// Create a DTO even if the response was a failure +$server = $response->dto(); + +// Create a DTO or throw an exception if the response is not successful +$server = $response->dtoOrFail(); +``` + +{% hint style="info" %} +Saloon will attempt to create a DTO from your response no matter the status of the response. This allows you to create "error" data transfer objects. If you don't want to use this functionality, you can use the `dtoOrFail` method which will throw a LogicException if the response is a failure. **You can customise what is considered a failed response** [**here**](handling-failures.md#customising-when-saloon-thinks-a-request-has-failed)**.** +{% endhint %} + +### PHPStan / TypeHinting DTOs + +Due to the way DTOs are created in Saloon, you can lose the type of DTO. This can reduce the developer experience. There are two ways to get around this issue. + +You can use an inline-doc block above the `dto`/`dtoOrFail` method call. + +```php +/** @var Server $server */ +$server = $response->dto(); +``` + +Or you can use the `createDtoFromResponse` method directly on your connector or request - which will use the return type specified. + +```php +$server = $request->createDtoFromResponse($response); +``` + +### Using a DTO to populate request data + +You may also allow your data transfer objects to go both ways, back into requests. You can do this easily with Saloon, just accept your DTO as an argument in the constructor of your request and then use the DTO to set default properties inside of the request. + +{% tabs %} +{% tab title="Definition" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Enums\Method;
+use Saloon\Http\Response;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class UpdateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::PUT;
+    
+    public function __construct(readonly protected Server $server)
+    {
+        //
+    }
+    
+    public function resolveEndpoint(): string
+    {
+        return '/servers/' . $this->server->id;
+    }
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'name' => $this->server->name,
+        ];
+    }
+    
+    public function createDtoFromResponse(Response $response): mixed
+    {
+        $data = $response->json();
+    
+        return new Server(
+            id: $data['id'],
+            name: $data['name'],
+            ipAddress: $data['ip'],
+        );
+    }
+}
+
+{% endtab %} + +{% tab title="Usage" %} +```php +send(new GetServerRequest(id: 12345)); +$server = $response->dto(); + +// Modify the server +$server->name = 'YEE-HAW-2'; + +// Update the server request + +$response = $connector->send(new UpdateServerRequest($server)); +``` +{% endtab %} +{% endtabs %} + +### Accessing the response from your DTO + +Sometimes debugging a DTO can be difficult, especially if you have passed the data object through your application and no longer have access to the original `Response` that you created the DTO from. Saloon can inject the response into your data transfer object for you if you use the `HasResponse` trait and the `WithResponse` interface. Let's add it to our existing `Server` DTO. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Traits\Responses\HasResponse;
+use Saloon\Contracts\DataObjects\WithResponse;
+
+class Server implements WithResponse
+{
+    use HasResponse;
+
+    public function __construct(
+        public readonly int $id,
+        public readonly string $name,
+        public readonly string $ipAddress,
+    ){}
+}
+
+ +Now whenever we retrieve an instance of our data transfer object, you will be able to access the underlying response that was created with it! + +```php +dto(); + +$response = $server->getResponse(); +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/debugging.md b/_docs/laravel-libs/saloon-docs/the-basics/debugging.md new file mode 100644 index 0000000..903566a --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/debugging.md @@ -0,0 +1,105 @@ +# 🔎 Debugging + +While building API integrations, sometimes you will send a request and the API will return an error. This could be due to sending the request badly or incorrect data. Sometimes debugging the request can be difficult - so Saloon has some helpers to resolve this. + +### Prerequisites + +Saloon's default debugging driver uses [Symfony's Var Dumper](https://github.com/symfony/var-dumper) library. If you're not using Laravel and do not have it installed, you can install it below. + +``` +composer require symfony/var-dumper +``` + +{% hint style="info" %} +Laravel already includes this library. +{% endhint %} + +### Debugging Request & Response + +The simplest way to debug a request and response is to use the `debug()` method on your connector before sending a request. This will output an easy-to-understand array of the request and the response. + +{% tabs %} +{% tab title="Connector" %} +```php +$connector = new ForgeConnector; + +$connector->debug()->send($request); +``` +{% endtab %} + +{% tab title="Request" %} +```php +$connector = new ForgeConnector; + +$connector->send($request->debug()); +``` +{% endtab %} +{% endtabs %} + +You can provide the `die` argument if you would like to terminate the application after receiving the response. + +```php +$connector->debug(die: true)->send($request); +``` + +This will provide an output in your terminal/browser like this: + +``` +Saloon Request (UserRequest) -> array:6 [ + "connector" => "Saloon\Tests\Fixtures\Connectors\TestConnector" + "request" => "Saloon\Tests\Fixtures\Requests\UserRequest" + "method" => "GET" + "uri" => "https://tests.saloon.dev/api/user" + "headers" => array:2 [ + "Host" => "tests.saloon.dev" + "Accept" => "application/json" + ] + "body" => "" +] + +Saloon Response (UserRequest) -> array:3 [ + "status" => 200 + "headers" => [] + "body" => "{"name":"Sam"}" +] +``` + +{% hint style="warning" %} +This output will show the request just before it is sent to the sender. If the sender (like Guzzle) adds any additional headers or changes the request, these changes will not be displayed. +{% endhint %} + +### Separate Debuggers + +You may also use `debugRequest` and `debugResponse` independently if you would like to debug just the request or response respectively. + +```php +debugRequest(); // $connector->debugRequest(die: true); + +$connector->debugResponse(); // $connector->debugResponse(die: true); +``` + +### Custom Debugger Handlers + +You may also provide a closure to the `debugRequest` and `debugResponse` methods if you would like to write your own debugging implementations. + +```php +debugRequest(function (PendingRequest $pendingRequest, RequestInterface $psrRequest) { + ray($psrRequest); +}); + +$connector->debugResponse(function (Response $response, ResponseInterface $psrResponse) { + ray($psrResponse); +}); +``` + diff --git a/_docs/laravel-libs/saloon-docs/the-basics/handling-failures.md b/_docs/laravel-libs/saloon-docs/the-basics/handling-failures.md new file mode 100644 index 0000000..ef51314 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/handling-failures.md @@ -0,0 +1,184 @@ +# 🔥 Handling Failures + +Saloon has a powerful exception handler with many descriptive exceptions you can use in your application. + +When you send a request, Saloon won't do anything if the request fails, but by default, it will use the status code to determine if a request is successful or not. The only exception to this is if Saloon cannot connect to an API, which will throw a `FatalRequestException`. + +```php +send(new ErrorRequest); + +$response->failed(); // true +$response->status(); // 500 +$response->body(); // {"message": "Server Error"} +``` + +### Always throw exceptions on failed requests + +You may wish to throw an exception whenever a request fails (4xx or 5xx response). You can add the `AlwaysThrowOnErrors` trait on your connector, and then every request that fails will throw an exception. + +```php +send(new ErrorRequest); + +// throws InternalServerErrorException (extends ServerException) + +$response->throw(); +``` + +### Response Exceptions + +Saloon's default exception handler contains the following exceptions based on the status code and severity of the exception. These are thrown depending on the method you use below. + +``` +SaloonException +├── FatalRequestException (Connection Errors) +└── RequestException (Request Errors) + ├── ServerException (5xx) + │ ├── InternalServerErrorException (500) + │ ├── ServiceUnavailableException (503) + │ └── GatewayTimeoutException (504) + └── ClientException (4xx) + ├── UnauthorizedException (401) + ├── PaymentRequiredException (402) + ├── ForbiddenException (403) + ├── NotFoundException (404) + ├── MethodNotAllowedException (405) + ├── RequestTimeOutException (408) + ├── UnprocessableEntityException (422) + └── TooManyRequestsException (429) +``` + +### Handling failures with promises + +When sending requests using `sendAsync` or using request pooling, you will receive a `PromiseInterface` instance. Since this class catches exceptions, Saloon will automatically pass the request exception in the `otherwise` block, and you do not have to use the `throw` method. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle successful response + }) + ->otherwise(function (RequestException $exception) { + // Handle failed request + }); +``` + +### Customising when Saloon thinks a request has failed + +You may integrate with an API which returns a 200 response status but with an error message in the response body. To handle this, you can extend the `hasRequestFailed` method on your connector or request. + +{% tabs %} +{% tab title="Connector" %} +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\Http\Response;
+
+class ForgeConnector extends Connector
+{
+    // {...}
+    
+    public function hasRequestFailed(Response $response): ?bool
+    {
+        return str_contains($response->body(), 'Server Error');
+    }
+}
+
+{% endtab %} + +{% tab title="Request" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\Response;
+
+class ErrorRequest extends Request
+{
+    // {...}
+    
+    public function hasRequestFailed(Response $response): ?bool
+    {
+        return str_contains($response->body(), 'Server Error');
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Customising the request exception + +By default, Saloon will use the exceptions [listed above](handling-failures.md#response-exceptions), but you may choose to return your own exception if a request has failed. Just extend the `getRequestException` method on either your connector or request. You will receive an instance of the response and a sender exception, which may be nullable. + +{% tabs %} +{% tab title="Connector" %} +```php +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add a trait to provide an implementation for the missing `body()` method. Saloon has a trait for all the common types of request bodies. + +Continue reading below to understand more about the specific body type that you need. + +{% content-ref url="json-body.md" %} +[json-body.md](json-body.md) +{% endcontent-ref %} + +{% content-ref url="multipart-form-body.md" %} +[multipart-form-body.md](multipart-form-body.md) +{% endcontent-ref %} + +{% content-ref url="stream-body.md" %} +[stream-body.md](stream-body.md) +{% endcontent-ref %} + +{% content-ref url="form-body-url-encoded.md" %} +[form-body-url-encoded.md](form-body-url-encoded.md) +{% endcontent-ref %} + +{% content-ref url="xml-body.md" %} +[xml-body.md](xml-body.md) +{% endcontent-ref %} + +{% content-ref url="string-plain-text-body.md" %} +[string-plain-text-body.md](string-plain-text-body.md) +{% endcontent-ref %} diff --git a/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/form-body-url-encoded.md b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/form-body-url-encoded.md new file mode 100644 index 0000000..477f207 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/form-body-url-encoded.md @@ -0,0 +1,184 @@ +# Form Body (URL Encoded) + +To get started, change your method to **POST, PUT or PATCH** depending on the requirements of the API. After that, you will need to add the `HasBody` interface to your request. Without this interface, Saloon will not send any request body to the HTTP client. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    protected Method $method = Method::POST;
+}
+
+ +Next, you will need to add the `HasFormBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasFormBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasFormBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/x-www-form-urlencoded` header for you when using the `HasFormBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]; + } +} +``` + +Sometimes there can be too many items to define as constructor arguments. If this is the case for you, you can require the user to provide an array, or even a DTO to populate the default body of your request. + +{% tabs %} +{% tab title="Using an array" %} +```php +payload; + } +} +``` +{% endtab %} + +{% tab title="Using a DTO (Data Transfer Object)" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasFormBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasFormBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected Server $server
+    ){}
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'ubuntu_version' => $this->server->ubuntuVersion,
+            'type' => $this->server->type,
+            'provider' => $this->server->provider,
+        ];
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the form request body: + +* add(string $key, mixed $value) -> **Add items to the form body** +* remove(string $key) -> **Remove items from the form body** +* merge(…$values) -> **Merge another array of items into the form body** +* set(array $value) -> **Overwrite the form body entirely** +* all(): array -> **Get all the values of the form body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->add('ubuntu_version', '22.04'); + +$request->body()->merge([ + 'type' => 'app', + 'provider' => 'ocean2', +]); + +$body = $request->body()->all(); + +// array: [ +// 'ubuntu_version' => '22.04', +// 'type' => 'app', +// 'provider' => 'ocean2', +// ] +``` + +### Connector Body + +If you would like to also have form body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared form body across every request, like an authentication token. + +```php + 'Sam', + ]; + } +} +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/json-body.md b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/json-body.md new file mode 100644 index 0000000..6b7e1a1 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/json-body.md @@ -0,0 +1,209 @@ +# JSON Body + +To get started, change your method to **POST, PUT or PATCH** depending on the requirements of the API. After that, you will need to add the `HasBody` interface to your request. Without this interface, Saloon will not send any request body to the HTTP client. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Enums\Method;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    protected Method $method = Method::POST;
+}
+
+ +Next, you will need to add the `HasJsonBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/json` header for you when using the `HasJsonBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]; + } +} +``` + +Sometimes there can be too many items to define as constructor arguments. If this is the case for you, you can require the user to provide an array, or even a DTO to populate the default body of your request. + +{% tabs %} +{% tab title="Using an array" %} +```php +payload; + } +} +``` +{% endtab %} + +{% tab title="Using a DTO (Data Transfer Object)" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected Server $server
+    ){}
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'ubuntu_version' => $this->server->ubuntuVersion,
+            'type' => $this->server->type,
+            'provider' => $this->server->provider,
+        ];
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the JSON request body: + +* add(string $key, mixed $value) -> **Add items to the JSON body** +* remove(string $key) -> **Remove items from the JSON body** +* merge(…$values) -> **Merge another array of items into the JSON body** +* set(array $value) -> **Overwrite the JSON body entirely** +* all(): array -> **Get all the values of the JSON body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->add('ubuntu_version', '22.04'); + +$request->body()->merge([ + 'type' => 'app', + 'provider' => 'ocean2', +]); + +$body = $request->body()->all(); + +// array: [ +// 'ubuntu_version' => '22.04', +// 'type' => 'app', +// 'provider' => 'ocean2', +// ] +``` + +### Connector Body + +If you would like to also have JSON body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared JSON body across every request, like an authentication token. + +```php + 'Sam', + ]; + } +} +``` + +### JSON Flags + +When using the `HasJsonBody` trait, you may want to customise the flags used when encoding the body to be sent to the API you are integrating with. You may do this with the `setJsonFlags` method. It's recommended that you set this within the constructor of your request or connector to ensure that the flags are always used. + +For example, if I know that my JSON will contain URLs, but I don't want the URL slashes to be escaped, I can use the `JSON_UNESCAPED_SLASHES` flag. You can also specify multiple flags at once by using the `|` pipe to separate the flags. + +```php +body()->setJsonFlags(JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR); + } +} +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/multipart-form-body.md b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/multipart-form-body.md new file mode 100644 index 0000000..aa197ab --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/request-body-data/multipart-form-body.md @@ -0,0 +1,149 @@ +# Multipart Form Body + +Multipart body (multipart/form-data) is often used in modern APIs as a way to upload a mixture of files and data. Saloon makes handling multipart bodies easy by providing you with a standardised way of interacting with the values to be sent. You don't have to worry about calculating boundaries or properly encoding the multipart values, you can just use simple arrays and a value object to define the values. + +To get started, change your method to **POST, PUT or PATCH** depending on the requirements of the API. After that, you will need to add the `HasBody` interface to your request. Without this interface, Saloon will not send any request body to the HTTP client. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+
+class UploadProfilePictureRequest extends Request implements HasBody
+{
+    protected Method $method = Method::POST;
+}
+
+ +Next, you will need to add the `HasMultipartBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasMultipartBody;
+
+class UploadProfilePictureRequest extends Request implements HasBody
+{
+    use HasMultipartBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: multipart/form-data` header for you when using the `HasMultipartBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### The MultipartValue + +To build up multipart data, Saloon uses a class `Saloon\Data\MultipartValue`. This class is used as a value object and when your request is sent, it will automatically be converted into a stream to be sent to the API. To see how to use this class, continue reading below. + +```php +filePath) + ]; + } +} +``` + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the multipart request body: + +* add(string $name, mixed $value, string $filename = null, array $headers = \[]) -> **Add a multipart value to the multipart body** +* attach(MultipartValue $value) -> **Attach a multipart directly to the multipart body** +* remove(string $key) -> **Remove an item from the multipart body** +* merge(... $arrays) -> **Merge another array of multipart values into the multipart body** +* set(array $value) -> **Overwrite the entire multipart body with a different set of values** +* all() -> **Get the array of multipart values** +* get(string $key) **-> Get an individual multipart value** +* isEmpty() **-> Check if the multipart body is empty** +* isNotEmpty() **-> Check if the multipart body is not empty** + +```php +body()->add( + name: 'picture', + contents: 'your-file-contents-or-stream', + filename: 'picture.png', // Optional file name + headers: [ + // Optional custom headers + ] +); + +// You may also get a multipart value by name. + +$request->body()->get('picture'); // MultipartValue class + +``` + +{% hint style="info" %} +The `contents` of the `MultipartValue` class can be either the raw-text contents of the file or a PHP stream/resource. +{% endhint %} + +### Connector Body + +If you would like to also have a multipart body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared value across every request. + +```php +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStreamBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStreamBody;
+
+    protected Method $method = Method::POST;
+    
+    // Define our own Content-Type...
+    
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'text/plain',
+        ];
+    }
+}
+
+ +{% hint style="info" %} +Saloon won't add a Content-Type header for you for plain stream bodies so you must define the Content-Type or the API might not accept the data. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php +stream; + } +} +``` + +{% hint style="info" %} +Saloon can accept a PHP resource or a PSR `StreamInterface` Stream implementation as the stream. +{% endhint %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the stream request body: + +* set(resource|StreamInterface $value) -> **Set the stream** +* all(): StreamInterface -> **Get the stream** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set(fopen('cowboy-hat.png', 'r')); + +$body = $request->body()->all(); // Returns PSR StreamInterface +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasStringBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStringBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStringBody;
+
+    protected Method $method = Method::POST;
+    
+    // Define our own Content-Type...
+    
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'text/plain',
+        ];
+    }
+}
+
+ +{% hint style="info" %} +Saloon won't add a Content-Type header for you for plain string bodies so you must provide your own Content-Type header. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStringBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStringBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected string $ubuntuVersion,
+        protected string $provider
+    ){}
+    
+    protected function defaultBody(): string
+    {
+        return 'Howdy, Partner. I want a ' . $this->ubuntuVersion . ' server through ' . $this->provider . ' provider!';
+    }
+}
+
+ +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the string request body: + +* set(string $value) -> **Overwrite the string body entirely** +* all(): array -> **Get the string body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set('Howdy, Partner'); + +$body = $request->body()->all(); + +// string: 'plain-text-response-body' +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasXmlBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasXmlBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasXmlBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/xml` header for you when using the `HasXmlBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + + + ' . $this->ubuntuVersion . ' + ' . $this->type . ' + ' . $this->provider . ' + + XML; + } +} +``` + +{% hint style="info" %} +While you are expected to return a raw string for the XML body, it can be tedious to write XML as text. We have built a library, [XML Wrangler](https://github.com/saloonphp/xml-wrangler) which allows you to read and write XML in a more developer-friendly way. +{% endhint %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the XML request body: + +* set(string $value) -> **Overwrite the XML body entirely** +* all(): array -> **Get the XML body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set(''); + +$body = $request->body()->all(); + +// string: 'plain-text-response-body' +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php +'; + } +} +``` + +### XML Wrangler + +You may be interested in a third-party library written by the maintainer of Saloon - XML Wrangler. It provides a modern syntax for reading and writing XML in PHP. + +{% content-ref url="../../installable-plugins/xml-wrangler.md" %} +[xml-wrangler.md](../../installable-plugins/xml-wrangler.md) +{% endcontent-ref %} diff --git a/_docs/laravel-libs/saloon-docs/the-basics/requests.md b/_docs/laravel-libs/saloon-docs/the-basics/requests.md new file mode 100644 index 0000000..f23e278 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/requests.md @@ -0,0 +1,125 @@ +# ✉ Requests + +API requests in Saloon each have a class. Within a request class, you define the endpoint, the HTTP method, and properties like headers, query parameters and body. + +### Getting Started + +Create a class that is in a similar place to your connector. The class should extend the `Request` abstract class. Inside the class, define a `$method` property and a `resolveEndpoint` method. The `resolveEndpoint` method will be combined with the connector's base URL. + +```php + If you have installed the Laravel plugin, you can use the **php artisan saloon:request** command to create a request. + +### Headers + +Some API requests require headers to be sent. To define default headers on your request, you can extend the `defaultHeaders` method. These will be merged with the connector's headers. + +```php +class GetServersRequest extends Request +{ + // ... + + protected function defaultHeaders(): array + { + return [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]; + } +} +``` + +You can also use the `headers` method on a request instance. + +```php +$request = new GetServersRequest; + +$request->headers()->add('Content-Type', 'text/plain'); +``` + +### Query Parameters + +Some API requests require query parameters to be sent. You can extend the `defaultQuery` method to provide these query parameters. + +```php +class GetServersRequest extends Request +{ + // ... + + protected function defaultQuery(): array + { + return [ + 'sort' => 'name', // ?sort=name + 'filter[active]' => 'true', // ?filter[active]=true + ]; + } +} +``` + +You can also use the `query` method on a request instance. + +```php +$request = new GetServersRequest; + +$request->query()->add('sort', 'provider'); +``` + +{% hint style="info" %} +Different APIs sometimes require different query string formats. Saloon uses PHP's built-in [`http_build_query`](https://www.php.net/manual/en/function.http-build-query.php) function to create query strings, but if you need something different, you can reformat the query string in the `Connector::handlePsrRequest()` method (see [Modifying the PSR-7 Request](../digging-deeper/psr-support.md#modifying-the-psr-7-request). +{% endhint %} + +### Timeout + +By default, Saloon will have a connection timeout of 10 seconds and a request timeout of 30 seconds. You can customise this by using the `HasTimeout` trait and specifying a `connectTimeout` and `requestTimeout` property. + +```php +use Saloon\Traits\Plugins\HasTimeout; + +class GetServersRequest extends Request +{ + use HasTimeout; + + protected int $connectTimeout = 60; + + protected int $requestTimeout = 120; +} +``` + +### Constructor Arguments + +Since requests are just classes, you can define a constructor to populate the request's properties. For example, if you are getting a specific resource you would need to pass its ID into the request class. + +```php +class GetServerRequest extends Request +{ + protected Method $method = Method::GET; + + public function __construct(protected readonly string $id) { + // + } + + public function resolveEndpoint(): string + { + return '/servers/' . $this->id; + } +} +``` + +```php +$request = new GetServerRequest('5664b05b-8b32-4523-a0d5-837f5080417a'); +``` diff --git a/_docs/laravel-libs/saloon-docs/the-basics/responses.md b/_docs/laravel-libs/saloon-docs/the-basics/responses.md new file mode 100644 index 0000000..5f667d6 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/responses.md @@ -0,0 +1,108 @@ +# 📡 Responses + +After sending a request, Saloon will return a `Response` class. This response class contains many helpful methods for interacting with your HTTP response like seeing the HTTP status code and retrieving the body. + +```php +send($request); + +$status = $response->status(); +$body = $response->body(); +``` + +{% hint style="info" %} +By default, Saloon will not throw an exception if a synchronous request fails. [Refer to the handling failures section for handling errors.](handling-failures.md) +{% endhint %} + +### Useful Methods + +Below are some of the key methods provided by Saloon's `Response` class. + +
MethodDescription
statusReturns the response status code.
headersReturns all response headers
headerReturns a given header
bodyReturns the raw response body as a string
jsonRetrieves a JSON response body and json_decodes it into an array.
arrayAlias of json
collectRetrieves a JSON response body and json_decodes it into a Laravel Collection. Requires illuminate/collections.
objectRetrieves a JSON response body and json_decodes it into an object.
xmlReaderUsed for XML responses - returns a XML Wrangler reader. Requires saloonphp/xml-wrangler.
domUsed for HTML responses - returns a Symfony DOM Crawler instance. Requires symfony/dom-crawler.
streamReturns the response body as an instance of StreamInterface
saveBodyToFileAllows you to save the raw body to a file or open file resource.
dtoConverts the response into a data-transfer object. You must define your DTO first, click here to read more.
dtoOrFailWill work just like dto but will throw an exception if the response is considered "failed".
ok, successful, redirect, failed, clientError, serverErrorMethods used to determine if a request was successful or not based on status code. The failed method can be customised.
throwWill throw an exception if the response is considered "failed".
getPendingRequestReturns the PendingRequest class that was built up for the request.
getPsrRequestReturns the PSR-7 request that was built up by Saloon
getPsrResponseReturn the PSR-7 response that was built up by the HTTP client/sender.
+ +### Asynchronous Responses + +When `sendAsync` or concurrent requests, Saloon will respond with a `GuzzleHttp\Promise\PromiseInterface.` The promise will contain a `Response` a class described above. When the request fails, Saloon will not use the `then` method but return an instance of `RequestException`in the `otherwise` block. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle successful response + }) + ->otherwise(function (Exception $exception) { + // Handle failed request + }); + +$promise->wait(); // Force the promise to be resolved +``` + +### Custom Responses + +Sometimes you may want to use your response class. This is useful if you want to add your methods or overwrite Saloon's response methods. Saloon allows you to overwrite the response at a connector level for all requests or at a per-request level for a granular response. + +The simplest way of registering a custom response is to use the `$response` property on either the connector or request. + +{% tabs %} +{% tab title="Connector" %} +
class ForgeConnector extends Connector
+{
+    // ...
+    
+    protected ?string $response = CustomResponse::class;
+}
+
+{% endtab %} + +{% tab title="Request" %} +
class GetServersRequest extends Request
+{
+    // ...
+    
+    protected ?string $response = CustomResponse::class;
+}
+
+{% endtab %} +{% endtabs %} + +When you need a more advanced way to define a custom response, use the `resolveResponseClass` method on either the connector or request. + +{% tabs %} +{% tab title="Connector" %} +```php +class ForgeConnector extends Connector +{ + // ... + + public function resolveResponseClass(): string + { + return CustomResponse::class; + } +} +``` +{% endtab %} + +{% tab title="Request" %} +```php +class GetServersRequest extends Request +{ + // ... + + public function resolveResponseClass(): string + { + return CustomResponse::class; + } +} +``` +{% endtab %} +{% endtabs %} diff --git a/_docs/laravel-libs/saloon-docs/the-basics/sending-requests.md b/_docs/laravel-libs/saloon-docs/the-basics/sending-requests.md new file mode 100644 index 0000000..e2bc93f --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/sending-requests.md @@ -0,0 +1,37 @@ +# 🚀 Sending Requests + +To start sending requests, instantiate your connector and use the `send` method. This method accepts a request class. + +```php +send($request); +``` + +### Asynchronous Requests + +To send an asynchronous request, use the `sendAsync` method, and you will receive an instance of `PromiseInterface`. You should define a `then` and `otherwise` method to receive the response or exception. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle Response + }) + ->otherwise(function (RequestException $exception) { + // Handle Exception + }); + +$promise->wait(); // Force the promise to be resolved +``` + +{% hint style="info" %} +Saloon uses Guzzle's Promises library. [Click here to learn more](https://github.com/guzzle/promises) +{% endhint %} diff --git a/_docs/laravel-libs/saloon-docs/the-basics/testing/README.md b/_docs/laravel-libs/saloon-docs/the-basics/testing/README.md new file mode 100644 index 0000000..e1aa272 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/the-basics/testing/README.md @@ -0,0 +1,525 @@ +# ✅ Testing + +### Introduction + +Writing tests for your API integrations is an important part of ensuring your application remains stable over time. This section of the documentation will walk you through how to use Saloon's testing helpers to mock API requests and write assertions to prove your application is handling requests and responses properly. + +#### What should you test? + +The general rule of thumb is that you should assume that the API you are integrating with has tests that ensure their API always returns what they tell you, so you don't have to worry about testing that specific endpoint returns the right data. + +You should, however, always test how your application handles the API response that comes back. What happens if the API is down or it returns a 500 error? What happens if your access token expires? You should make sure your application can handle these scenarios. + +#### Why use fake responses and fixtures instead of making the API calls every time? + +When running your application tests, you are likely going to be running them over and over again which might incur charges or hit API rate limits. Instead, you can either write a fake response or Saloon can record an API call once and re-use that same response in all subsequent tests. + +Faking API responses are typically much faster as they do not require an internet connection or potentially long wait times. + +### Getting Started + +#### The MockClient + +Saloon's testing starts with the **MockClient** class. This class can be instantiated locally for testing individual requests or used globally to test an API call nested deep in your application. Inside the MockClient, you can define requests and responses that should be returned instead of a real API call. + +```php +use Saloon\Http\Faking\MockClient; + +test('my test', function () { + $mockClient = new MockClient([ + GetServersRequest::class => MockResponse::make(body: '', status: 200), + ]); + + $connector = new ForgeConnector; + $connector->withMockClient($mockClient); +}); +``` + +You use the key of the MockClient to define a request that should be mocked. You can also use a URL pattern. You can use an asterisk (**\***) to act as a wild card. + +```php +$mockClient = new MockClient([ + 'forge.laravel.com/api/v1/servers' => MockResponse::make(body: '', status: 200), + 'forge.laravel.com/*' => MockResponse::make(body: '', status: 200), +]); +``` + +You can also use a sequence of responses which will be returned regardless of the API call. + +```php +$mockClient = new MockClient([ + MockResponse::make(body: 'First', status: 200), + MockResponse::make(body: 'Second', status: 200), + MockResponse::make(body: 'Third', status: 200), +]); +``` + +You can also use a closure for more advanced mock responses. + +```php +$mockClient = new MockClient([ + GetServersRequest::class => function (PendingRequest $pendingRequest) { + return MockResponse::make(...); + }, +]); +``` + +#### Manual Fake Responses + +There are two ways to define a response, you can do it manually with `MockResponse::make()` which is suitable for simple responses. It will accept three arguments: body, HTTP status code and headers. You may pass a string or an array into the body argument. If you provide an array, it will automatically be converted into JSON. + +```php +$mockClient = new MockClient([ + GetUserRequest::class => MockResponse::make( + body: ['user' => ['name' => 'Sam']], + status: 200, + headers: ['Content-Type' => 'application/json'] + ), +]); +``` + +#### Recorded Responses (Fixtures) + +The second way to define a response is with `MockResponse::fixture()` this is suitable for testing larger API responses or to save time. With this, Saloon will make a real API call for the first time, and then store the API call inside of a file in your application, so that when you run the test again, the response will be used and not make a real API call. + +```php +$mockClient = new MockClient([ + GetUserRequest::class => MockResponse::fixture('user'); +]); +``` + +### Testing your application + +Now that you have an idea of how testing works in Saloon, let's put it into practice. This section of the documentation will teach you how to write a MockClient for your application. This guide assumes you have already set up a test suite for your application. If you are new to testing, we recommend [PEST](https://pestphp.com/). + +{% hint style="info" %} +This section of the documentation uses the new **Global Mock Client** introduced in Saloon v3.5. Make sure that you are using this version of Saloon by running: `composer update "saloonphp/*"` +{% endhint %} + +#### Setup + +First of all, you will need to add a method which should run before every test in your application. Without this, the global mock client will leak into other tests and may break your test suite. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\Http\Faking\MockClient; + +uses() + ->beforeEach(fn () => MockClient::destroyGlobal()) + ->in(__DIR__); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\Http\Faking\MockClient; + +class RequestTest extends TestCase +{ + protected function setUp(): void + { + MockClient::destroyGlobal(); + } +} +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +If you are using Laravel and have installed the [Laravel plugin](../../installable-plugins/laravel-integration.md), you do not need to destroy the global mock client before each test as the plugin will do this for you. +{% endhint %} + +#### Writing tests + +Let's say that your application has a controller which queries the Laravel Forge API and stores the list of servers in the database. We'll use the global mock client to return fake data so we don't send an API call to the external API. + +Saloon will detect the global mock client and will use the mock response which you have defined instead of sending a real API call. It's recommended to define your mock at the top of a test. + +{% tabs %} +{% tab title="Test" %} +```php + MockResponse::make( + body: [ + 'data' => [ + ['name' => 'WEB-1', 'ip' => '192.168.0.1'], + ['name' => 'WEB-2', 'ip' => '192.168.0.2'], + ], + ], + status: 200, + ), + ]); + + $this->assertDatabaseCount('servers', 0); + + // Call our controller which will invoke the Saloon request + + $this + ->getJson('/api/servers/sync') + ->assertOk(); + + // Assert our database has created servers! + + $this->assertDatabaseCount('servers', 2); + + $this->assertDatabaseHas('servers', [ + 'name' => 'WEB-1', + 'ip' => '192.168.0.1', + ]); + + $this->assertDatabaseHas('servers', [ + 'name' => 'WEB-2', + 'ip' => '192.168.0.2', + ]); +}); +``` +{% endtab %} + +{% tab title="Controller Code" %} +```php +send(new GetServersRequest)->array('data'); + + foreach($servers as $server) { + DB::table('servers')->insert([ + 'name' => $server['name'], + 'ip' => $server['ip'], + ]); + } + + return response('Synced servers', 200); + } +} +``` +{% endtab %} +{% endtabs %} + +### Recording Requests (Fixtures) + +So far we have covered testing where you have to write your mock response yourself. This works well for small responses but most API responses will have a lot more data. As previously mentioned, Saloon supports recording requests in your tests. This works by allowing the test to make a real API call the first time and then on subsequent API calls, the same response will be used. + +This works by saving the response as a file in your application which can be committed in your project and used for later. + +{% hint style="warning" %} +Make sure that you do not accidentally store sensitive information from the real API call. You can read more about redacting fixtures [here](./#redacting-recorded-responses-fixtures). +{% endhint %} + +#### Example with fixtures + +Let's take a look at the example above but with fixtures, as you can see nothing else has to change except that we are using `MockResponse::fixture()`. It accepts one argument which is the name of the fixture. + +
<?php
+
+use Saloon\Http\Faking\MockClient;
+use Saloon\Http\Faking\MockResponse;
+
+test('can store servers in the database from laravel forge', function () {
+    MockClient::global([
+        GetServersRequest::class => MockResponse::fixture('servers'),
+    ]);
+
+    $this->assertDatabaseCount('servers', 0);
+    
+    // Call our controller which will invoke the Saloon request
+
+    $this
+        ->getJson('/api/servers/sync')
+        ->assertOk();
+        
+    // Assert our database has created servers!
+        
+    $this->assertDatabaseCount('servers', 2);
+    
+    $this->assertDatabaseHas('servers', [
+        'name' => 'REAL-SERVER-1',
+        'ip' => '192.168.0.1',
+    ]);
+    
+    $this->assertDatabaseHas('servers', [
+        'name' => 'REAL-SERVER-2',
+        'ip' => '192.168.0.2',
+    ]);
+});
+
+ +#### Customising Fixture Location + +By default, fixtures will be stored in `tests/Fixtures/Saloon`. You can customise the fixture location by using the `setFixturePath` method on the `MockConfig` class. + +```php +MockConfig::setFixturePath('tests/other-directory'); +``` + +#### Namespacing Fixtures + +With multiple API integrations, having all the fixtures in one directory can get messy. You can use `/` to create folders for your fixtures. + +```php +MockClient::global([ + GetServersRequest::class => MockResponse::fixture('forge/servers'), +]); +``` + +{% hint style="warning" %} +You should be cautious when naming fixture folders - some operating systems like MacOS do not have case sensitivity for folders but some Unix-based systems like Linux do. This can result in fixtures not being found. It's recommended to use lowercase names. +{% endhint %} + +#### Refreshing Fixtures + +If you need to refresh a fixture, all you have to do is delete the JSON file and re-run your test. Saloon will see the file is no longer there and will re-record the request. + +### Testing individual requests and SDKs + +Occasionally, you might want to write unit tests for individual requests to ensure you are sending the right information to an API. If you are building an SDK, then you may wish to follow this guide for testing your SDK. + +#### Using the withMockClient method on your connector + +Instead of using the global mock client, you can create a local instance of a MockClient and pass it into your connector or request using the `withMockClient` method. + +
<?php
+
+test('a request sends the correct body', function () {
+    $mockClient = new MockClient([
+        CreateServerRequest::class => MockResponse::make('Server Created', 200),
+    ]);
+
+    $connector = new ForgeConnector;
+    $connector->withMockClient($mockClient);
+    
+    $connector->send(new CreateServerRequest($name, $ip));
+    
+    $mockClient->assertSent(function (Request $request) {
+        return $request->body()->all() === ['name' => $name, 'ip' => $ip];
+    });
+});
+
+ +### Assertions + +Saloon has a variety of built-in assertion methods which you can also use in your test to assert that Saloon is sending the right information to the third-party API. You can define a variable for your MockClient and call the various assertion methods inside of your test. + +```php + MockResponse::make(...), + ]); + + // Your application code... + + $mockClient->assertSent(GetServersRequest::class); + + $mockClient->assertSentCount(1); +}); +``` + +Saloon has the following assertions: + +#### assertSent / assertNotSent + +These methods will check that a specific request has been sent. + +```php +$mockClient->assertSent(GetServersRequest::class); +``` + +The method can also accept a closure which should return true for more advanced assertions. + +```php +$mockClient->assertSent(function (Request $request, Response $response) { + return $request instanceof GetServersRequest; +}); +``` + +#### assertSentCount + +This method allows you to assert that a specific number of requests has been sent. + +```php +$mockClient->assertSentCount(1); +``` + +The method also accepts a second argument which allows you to check the amount a specific request class was sent. + +```php +$mockClient->assertSentCount(2, GetServersRequest::class); +$mockClient->assertSentCount(1, CreateServerRequest::class); +``` + +#### assertNothingSent + +This method will assert that no requests have been sent. + +```php +$mockClient->assertNothingSent(); +``` + +### Preventing Stray Requests + +You may want to prevent real API calls from being attempted in your tests. You can use `Config::preventStrayRequests()` which will throw an exception if a real API call is attempted. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\Config; + +Config::preventStrayRequests(); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\Config; + +class TestCase extends BaseTestCase +{ + protected function setUp(): void + { + parent::setUp(); + Config::preventStrayRequests(); + } +} +``` +{% endtab %} +{% endtabs %} + +{% hint style="warning" %} +Fixtures will still be recorded and not counted as stray requests. +{% endhint %} + +### Preventing Fixtures Being Recorded + +While running tests, you may wish to prevent Saloon from attempting to record any further fixtures. This is useful for CI like GitHub actions where you shouldn't expect any fixtures to be recorded. You can use `MockConfig::throwOnMissingFixtures()` to prevent this from happening. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\MockConfig; + +MockConfig::throwOnMissingFixtures(); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\MockConfig; + +class TestCase extends BaseTestCase +{ + protected function setUp(): void + { + MockConfig::throwOnMissingFixtures(); + } +} +``` +{% endtab %} +{% endtabs %} + +### Redacting Recorded Responses / Fixtures + +When using fixtures to record real responses from an API - sometimes the API will return some sensitive information that you shouldn't store in your application's repository, like names of real people, financial data or emails. With Saloon, you can create a custom fixture class and provide a few methods to obscure the information when the data is stored. You can even provide closures for the data replacement so you can use tools like Faker to replace data like-for-like. + +{% hint style="info" %} +The first time the request is made and the fixture is stored, the original response won't be redacted. Only future requests made with the fixture will use the redacted recording. +{% endhint %} + +First, create a new class in your tests directory and extend the base `Fixture` class provided by Saloon. Next, extend the `defineName` method and give the fixture a name. You can still use slashes in this directory to denote folders. + +Now you can use a few different methods to redact your fixture data. + +* defineSensitiveHeaders for headers +* defineSensitiveJsonParameters for JSON responses +* defineSensitiveRegexPatterns for other body types + +The methods expect a key => value array where the key is the property that is being redacted and the value is the replacement. You can use a string as the replacement or use a closure for more advanced replacement engines like using faker. + +
<?php
+
+namespace Tests\Fixtures\Forge\SingleServerFixture;
+
+use Saloon\Http\Faking\Fixture;
+
+class SingleServerFixture extends Fixture
+{
+    protected function defineName(): string
+    {
+        return 'forge/singleServer';
+    }
+    
+    protected function defineSensitiveHeaders(): array
+    {
+        return [
+            'Authorization' => 'REDACTED',
+        ];
+    }
+
+    protected function defineSensitiveJsonParameters(): array
+    {
+        return [
+            'name' => 'REDACTED',
+            'password' => function () {
+                return faker()->password;
+            },
+        ];
+    }
+    
+    protected function defineSensitiveRegexPatterns(): array
+    {
+        return [
+            '/@[a-z0-9_]{0,100}/' => 'REDACTED-TWITTER-HANDLE',
+        ];
+    } 
+}
+
+ +Once you have created your custom fixture class with the redaction configuration, you can simply use it instead of `MockResponse::fixture()` in your tests. All detection methods in the mock client work with this type of fixture too. + +
<?php
+
+$mockClient = new MockClient([
+    GetServerRequest::class => new SingleServerFixture;
+]);
+
+ +### Using Saloon's Laravel Facade + +If you have installed the [official Laravel plugin](../../installable-plugins/laravel-integration.md), then you can use the `Saloon::fake()` method as an alias of `MockClient::global()`. + +```php +use Saloon\Laravel\Facades\Saloon; + +Saloon::fake([ + GetServersRequest::class => MockResponse::make(body: '', status: 200), +]); +``` diff --git a/_docs/laravel-libs/saloon-docs/upgrade/upgrading-from-v2.md b/_docs/laravel-libs/saloon-docs/upgrade/upgrading-from-v2.md new file mode 100644 index 0000000..7aa4c56 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/upgrade/upgrading-from-v2.md @@ -0,0 +1,233 @@ +# 🌳 Upgrading from v2 + +Saloon version three comes with many improvements over version two, but most of the improvements were internal changes, so the upgrade to v3 from v2 shouldn't be too cumbersome. If you haven't already, it's recommended to read through ["What's new in v3"](whats-new-in-v3.md) to get an idea of what has changed before making the upgrade. + +### Upgrade Saloon's Packages + +First of all, you should bump Saloon to the next major version in your `composer.json` file. You should also update any of the following plugins if you have them installed. + +* `saloonphp/saloon` to `^3.0` +* `saloonphp/laravel-plugin` to `^3.0` +* `saloonphp/cache-plugin` to `^3.0` +* `saloonphp/laravel-http-sender` to `^2.0` +* `saloonphp/rate-limit-plugin` to `^2.0` +* `saloonphp/pagination-plugin` to `^2.0` + +After that, make sure to run the following command to update your `composer.lock` file and your `vendor` directory. + +```bash +composer update "saloonphp/*" +``` + +{% hint style="info" %} +The above command will just update the `saloonphp` libraries. If you have other libraries using Saloon you should make sure that they are updated as well. +{% endhint %} + +### High Impact Changes + +High-impact changes will most likely be things that everyone needs to update. + +#### Minimum TLS 1.2 version enforced + +From version three, Saloon uses Guzzle `^7.6` which introduced a new option to configure a minimum TLS version. With Saloon v3, Saloon has set this default to **TLS 1.2.** If any of your API integrations require a lower level of TLS security, you can change the Saloon config while your application is loading. + +```php +FindReplaceuse Saloon\Contracts\Connectoruse Saloon\Http\Connectoruse Saloon\Contracts\Requestuse Saloon\Http\Requestuse Saloon\Contracts\PendingRequestuse Saloon\Http\PendingRequestuse Saloon\Contracts\Responseuse Saloon\Http\Response + +{% hint style="info" %} +There have been many other interfaces removed in v3 however it's unlikely that your application would have used them. They are listed below. +{% endhint %} + +#### HasBody Trait Renamed to HasStringBody + +During some of the code review to improve readability, the `HasBody` body trait has been renamed to `HasStringBody` to be more explicit. If any of your requests send a **plain string body**, you should find and replace this trait. + +
FindReplace
use Saloon\Traits\Body\HasBodyuse Saloon\Traits\Body\HasStringBody
use HasBodyuse HasStringBody
+ +### Medium Impact Changes + +Medium-impact changes are changes that come up for some people but not others. + +#### SendAndRetry method argument name changes + +The second argument of the `$connector->sendAndRetry()` method has been renamed from `maxAttempts` to `tries`. If you are using named arguments then you will need to replace this name. + +
$connector->sendAndRetry(
+    request: $request,
+    tries: 5,
+);
+
+ +#### SendAndRetry handler now expects a Request class and not PendingRequest + +If you previously used the `handleRetry` argument when using `$connector->sendAndRetry()` - Saloon will now send an instance of `Request` instead of `PendingRequest` through the closure. + +
$connector->sendAndRetry(
+    request: $request,
+    tries: 5,
+    interval: 0,
+    handleRetry: static function (Throwable $exception, Request $request) {
+        // $request->headers()->add();
+    },
+);
+
+ +#### Config Method Changes + +With version three, some of the methods in the `Saloon\Config` class have been renamed. These changes have been listed below and you should make sure to rename them if you have used them in your application. + +| Find | Replace | +| ----------------------------- | --------------------------------- | +| `Config::middleware()` | `Config::globalMiddleware()` | +| `Config::resetMiddleware()` | `Config::clearGlobalMiddleware()` | +| `Config::resolveSenderWith()` | `Config::setSenderResolver()` | +| `Config::setDefaultSender()` | `Config::$defaultSender =` | + +### Low Impact Changes + +Low-impact changes are changes that are unlikely to come up unless you have overwritten some of Saloon's functionality or used its interfaces. It's still worth looking through to make sure you haven't missed anything. + +#### Methods Renamed On MockResponse + +On the `MockResponse` class Saloon had a few methods which have now been renamed to be more consistent with the rest of Saloon. These changes are: + +* `getBody()` has changed to `body()` +* `getHeaders()` has changed to `headers()` +* `getStatus()` has changed to `status()` + +#### Middleware Arguments Changed + +Saloon v3 introduced the ability to reorder middleware. With this, the old `prepend` argument on middleware methods has been replaced with a `pipeOrder` argument. Additionally, the second argument for the middleware is now `name` . + +#### Methods Removed From PendingRequest Class + +The following methods have now been removed from the `PendingRequest` class. You can use the suggested replacement if you are using them in your application. + +
OldSuggested Replacement
$pendingRequest->send()$pendingRequest->getConnector()->send()
$pendingRequest->sendAsync()$pendingRequest->getConnector()->sendAsync()
$pendingRequest->getSender()$pendingRequest->getConnector()->sender()
+ +#### Promise Execution Changes + +Previously, Saloon's `PendingRequest` and middleware would be invoked before an asynchronous request was sent (using `$connector->sendAsync()`) - now Saloon has fixed this issue and the `PendingRequest` and middleware will only be invoked while the `Promise` is being resolved - at the same time as sending the request. If your application depended on the old way the middleware was invoked you should make sure your application isn't affected by this change. + +#### SimulatedResponsePayload Class Renamed + +Previously, the `MockResponse` would extend a class called `SimulatedResponsePayload`. This class has now been renamed to `FakeResponse`. Additionally, methods on the `PendingRequest` like `$pendingRequest->setSimulatedResponsePayload()` has been renamed to `$pendingRequest->setFakeResponse()`. If you were extending the old class or using the methods to set the fake response in middleware, you should rename these methods. + +#### Sender Contract Updated + +The `Sender` interface has been completely rewritten in Saloon v3. Instead of just the `sendRequest` method. You now have to define three methods. If you have made a custom sender in Saloon, you should make sure this is updated. + +```php + + +Show Removed Interfaces + +* src/Contracts/Arrayable.php +* src/Contracts/Authenticatable.php +* src/Contracts/CanThrowRequestExceptions.php +* src/Contracts/Connector.php +* src/Contracts/DebuggingDriver.php +* src/Contracts/Dispatcher.php +* src/Contracts/HasConfig.php +* src/Contracts/HasDebugging.php +* src/Contracts/HasDelay.php +* src/Contracts/HasHeaders.php +* src/Contracts/HasMiddlewarePipeline.php +* src/Contracts/HasMockClient.php +* src/Contracts/HasPagination.php +* src/Contracts/HasQueryParams.php +* src/Contracts/IntegerStore.php +* src/Contracts/MiddlewarePipeline.php +* src/Contracts/MockClient.php +* src/Contracts/Paginator.php +* src/Contracts/PendingRequest.php +* src/Contracts/Pipeline.php +* src/Contracts/Pool.php +* src/Contracts/Request.php +* src/Contracts/Response.php +* src/Contracts/SimulatedResponsePayload.php + + + +#### The Base BodyRepository Class Is No Longer Stringable + +If you have made your own `BodyRepository` class from the base class and relied on the `__toString` method this has now been removed. Additionally, the interface has been updated and now requires a `toStream()` method. Inside here, you must define how to convert your body type into a Stream using the provided `StreamFactory`. + +#### Timeout Enum Removed + +The old `Timeout` enum has now been removed. If your application used to use this method, you should migrate to use `Config::$defaultConnectionTimeout` and `Config::$defaultRequestTimeout`. + +#### ToArray Method Removed From MultipartValue + +Previously, the `MultipartValue` object had a `toArray` method. Now that all body repositories are converted into Streams, this method is no longer required. + +#### SimulatedSender Removed + +The `SimulatedSender` class which would be used if you were mocking or had a cached response has now been removed. + +### Did we miss anything? + +If we forgot to add something to this upgrade please let us know by [opening an issue](https://github.com/saloonphp/saloon/issues). diff --git a/_docs/laravel-libs/saloon-docs/upgrade/whats-new-in-v3.md b/_docs/laravel-libs/saloon-docs/upgrade/whats-new-in-v3.md new file mode 100644 index 0000000..8c2efb3 --- /dev/null +++ b/_docs/laravel-libs/saloon-docs/upgrade/whats-new-in-v3.md @@ -0,0 +1,155 @@ +# 🪄 What's new in v3 + +We are excited to announce the release of Saloon version three, which is designed to provide an even better developer experience than before. This version comes with numerous internal changes that enhance maintainability, performance, and code readability. We have taken into account the feedback we received from users of Saloon v2 and made intentional modifications to improve your experience. + +To begin it's worth mentioning that Saloon has become a lot more lightweight in version three! + +> **333 changed files** with **4,063 additions** and **7,576 deletions** + +### Changes in version three + +#### Improved Pagination + +One of the biggest changes is how pagination in Saloon works. After seeing a few people use it - we felt that the developer experience could be better, so we revisited the whole feature. With Saloon v3, it no longer comes bundled into Saloon which reduces code but the pagination plugin provides a beautiful, expressive way to build and customise paginators. + +One of the motivations for rebuilding the pagination was customisation. Previously, you would have to extend the paginator class you are already using and guess which methods needed to be changed. The new pagination has been massively simplified and each of the paginators use the same methods to apply their pagination. This makes them much easier to build and maintain. Here is how the pagination definition looks in version three: + +```php +json('next_page_url')); + } + + // Get page items... + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +#### PSR Support + +Another important change to Saloon v3 was to lean more into the building and use of PSR-7 requests. Previously, Saloon would use Guzzle's configuration options to build up query parameters, request body and the URI. Now, Saloon builds all PSR requests in-house and passes that request to the sender. This provides a few key benefits over letting Guzzle handle it: + +* **Better developer experience** - with less hidden "magic" going on behind the scenes, you'll be able to debug and dump the PSR request Saloon creates to see how your request will be sent and what you're sending. +* **Decoupled further from Guzzle** - Saloon now only uses Guzzle to send your requests which means Saloon is much less dependent on Guzzle. +* **Lower-level customization** - You will be able to modify the PSR-7 request before it is sent, which gives you much better control than before. +* **New PSR methods -** You will now be able to create a PSR-7 request from a `PendingRequest` class. + +{% hint style="info" %} +This is an internal change only, and you won't need to change how your implementation works. You'll still use connectors and requests. +{% endhint %} + +#### Global Retry System + +Another really exciting feature in version three is the ability to configure retrying functionality at a connector level for all of your requests. Previously, the only way to configure the retry functionality was to do it in-line like this: + +```php +$response = $connector->sendAndRetry($request, 5); +``` + +This worked well, but it doesn't really follow one of Saloon's core values - to have beautiful, reusable code. Now you can define retrying at a class level. You just have to add the `$tries` property to either your connector or request to get it to work. After this, if you use `$connector->send()` and the request fails, it will be retried automatically. This is especially useful for SDK development or building against unstable APIs that need retrying at a connector level. + +```php +class ForgeConnector extends Connector +{ + /** + * The number of times a request should be retried if a failure response is returned. + * + * Set to null to disable the retry functionality. + */ + public ?int $tries = 5; +} +``` + +#### New Response Body Methods + +Saloon version three has a few new methods for the `Response` class to make it even easier to use in your application. + +* **saveBodyToFile($pathOrResource)** - This method allows you to save the raw body straight to a file or into an open file resource while keeping memory usage low. +* **getRawStream()** - This method is similar to the existing `stream()` method but will return a file `resource` instead of a `StreamInterface`. This method is really useful when passing the stream into other libraries like League's Flysystem library. +* **getConnector()** - This method is a nice shortcut to get the connector from the response. +* **getPsrRequest()** - This method gives you the PSR request that was built when sending the request - which is the lowest level request class before going through the HTTP client. + +#### Removed Interfaces For Maintainability + +With Saloon v2 - almost every class had an interface that acted as a blueprint for how the class should be structured. This was a decision made in version two to help make Saloon as flexible as possible. With version three, the decision was made to go back on this flexibility. While the added flexibility of giving the developer the freedom to make their own implementations - it added unnecessary complication and blocked Saloon from nice features and methods that could have been added before version three. + +We believe that most Saloon users would just use Saloon's implementation and adequate customization can be achieved with inheritance. + +Many interfaces (contracts) were removed with version three but some of the major ones include: + +* **Saloon\Contracts\Connector** +* **Saloon\Contracts\Request** +* **Saloon\Contracts\PendingRequest** +* **Saloon\Contracts\Response** + +The abstract classes still exist, but without the interfaces - the maintainability of Saloon v3 has improved massively. This means that the current version can be maintained for longer and new features can be released faster and without major version changes. + +#### Minimum TLS 1.2 Security + +Saloon version three requires Guzzle `^7.6` which introduced support for a minimum TLS version. Since TLS 1.1 has been deprecated for almost three years, Saloon has made the minimum version **TLS 1.2**. This is to promote more secure API integrations and follow best practices however it can be changed using configuration if required. + +#### Better Middleware Order + +The previous version introduced support for middleware in Saloon and allowed users to add their own middleware. This also introduced some challenges with how some of Saloon's other features worked like mocking and authenticators. Often when the user adds their own middleware, they may not see headers from authenticators or mock clients being applied to the `PendingRequest` class. Saloon v3's middleware order has been improved for the best feature compatibility. + +If you are curious, this is how the new middleware order looks: + +1. Plugins are "booted" +2. Request and connector properties (Headers, Query Parameters, Config, Middleware) are merged +3. Request and connector body is merged +4. Request and connector delay is merged +5. Authenticators are invoked and their logic applied to the `PendingRequest` +6. Request and connector is "booted" +7. Headers are validated +8. Delay is invoked (if applied) +9. Middleware is run in the following order: + 1. Global middleware + 2. Mock client finds a fake response (if present) + 3. Plugin middleware + 4. **User-added middleware** + 5. Debugging middleware is run (for the final object) + +#### Simplified Debugging + +Saloon v2 shipped with some useful debugging functionality. It came with numerous drivers for different outputs and worked nicely. With version three, it was decided that debugging should be simpler. From version three, if you need to debug your request or response, you can now use the `debug` method and pass in a closure to see either the `PendingRequest` , PSR request or `Response` class while it is being sent. + +Additionally, changes were made to the middleware pipeline to allow the debugging middleware to always run at the end of the pipeline, ensuring you'll always see the final result. + +```php +$connector->debugRequest(static function (PendingRequest $pendingRequest, Requestinterface $psrRequest) { + dd($pendingRequest->headers()); +}); + +$connector->debugResponse(static function (Response $response) { + dd($response->body()); +}); +``` + +#### Better Asynchronous Promise Handling + +With Saloon v3, promises are handled better. Previously, the `PendingRequest` class would be built up, and middleware run and then the `Promise` was created. With version three, a promise is created straight away and the `PendingRequest` and middleware is only invoked when the promise is being sent. This is good for plugins that need to run when a request is being sent like the rate limit plugin. + +#### SDK Helpers + +Last, but not least - Saloon v3 has shipped with a `BaseResource` class which is a class that was recommended in the [Building SDKs](../the-basics/building-sdks.md#request-resources) chapter of the documentation. Since this class is only small and provides value to the SDK developer, this class has now been bundled. diff --git a/_docs/openapi_specs_contracts-api.yaml b/_docs/openapi_specs_contracts-api.yaml new file mode 100644 index 0000000..581068d --- /dev/null +++ b/_docs/openapi_specs_contracts-api.yaml @@ -0,0 +1,59769 @@ +openapi: 3.0.3 +info: + title: Alfa API + contact: + name: API Support + email: baas_support@alfabank.ru + version: 1.0.0 +externalDocs: + description: Документация Alfa API + url: https://developers.alfabank.ru/old +servers: +- url: https://sandbox.alfabank.ru/api/ + description: Sandbox server API +- url: https://sandbox.alfabank.ru/oidc/ + description: Sandbox server OIDC +security: +- bearerAuth: [] +tags: +- name: BonusNumbers + description: Получение бонусных номеров карт клиента +- name: UserCompliance + description: Проверка актуальности сведений клиента +- name: Transactions + description: Операции по счетам +- name: Customer-info + description: Профиль организации +- name: OIDC + description: "Получение/обновление токена доступа, Получение информации о пользо\ + вателе, Получение Client Secret" +- name: Signature + description: Электронная подпись +- name: Payments + description: Платёжные поручения +- name: PaymentRegistries + description: Реестры рублёвых платежей +- name: Escrow-accounts + description: Функционал АПИ для застройщиков +- name: Loans + description: Кредиты +- name: Webhooks + description: Подписки на события +- name: Selfemployed-Agreements + description: Онбординг самозанятых и оформление с ними соглашений +- name: Selfemployed + description: Операции с самозанятыми в системе +- name: Payouts-processing + description: Выплаты исполнителям +- name: Selfemployed-Dictionaries + description: Справочники в части работы с самозанятыми +- name: Poa + description: Операции с машиночитаемыми доверенностями (МЧД) +- name: Beneficiaries + description: Работа с бенефициарами +- name: Accounts + description: Счета ФЛ +- name: Cards + description: Карты ФЛ +- name: OperationsHistory & Statements + description: История операций и выписки ФЛ +- name: Reports + description: Справки ФЛ +- name: Limits + description: Лимиты ФЛ +- name: Loyalty + description: Программа лояльности ФЛ +- name: DebitCards + description: Дебетовая анкета +- name: SBP + description: Сервисы для СБП +- name: B2B SPB 1C + description: API-интерфейс для интеграции AlfaAPI с 1С +- name: b2cpay + description: Сервисы b2cpay +- name: Credit Offers + description: Кредитные предложения физического лица +- name: C2B SBP + description: Операции СБП для C2B +- name: AlfaSecurity + description: Альфа Безопасность +- name: Logistics + description: Логистика / SFA Delivery +- name: Channel-Provider + description: SFA Delivery. Логистический центр +- name: Aff-integration + description: Интеграция с AFF +- name: Business Lounge + description: Сервисы для интеграции NFS с внешними партнерами +- name: DFA + description: Серфисы ЦФА +- name: Crypto-Service + description: Управление сертификатами шифрования и электронной подписи +- name: Claims + description: Работа с обращениями +- name: Order-Core + description: Управление заказом партнеров +- name: Self-encashment + description: Самоинкассация +- name: Partner + description: Сервисы Партнёрской Программы ММБ +- name: Mathmod scorings + description: Проверка контрагента +- name: Offices-rates + description: Выгрузка курсов валют по запросу в разрезе офисов +paths: + /token: + post: + tags: + - OIDC + summary: Получение токена доступа + description: Получение токена доступа + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/TokenRequest' + required: true + responses: + "200": + description: OK + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + Cache-Control: + schema: + type: string + example: no-store + enum: + - no-store + Pragma: + schema: + type: string + example: no-cache + enum: + - no-cache + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + "400": + description: BAD REQUEST + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + Cache-Control: + schema: + type: string + example: no-store + enum: + - no-store + Pragma: + schema: + type: string + example: no-cache + enum: + - no-cache + content: + application/json: + schema: + $ref: '#/components/schemas/TokenError' + "404": + description: NOT FOUND + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + "429": + description: Cлишком много запросов в заданный период + "503": + description: Сервер временно недоступен + /userinfo: + get: + tags: + - OIDC + summary: Получение информации о пользователе + description: Получение информации о пользователе + responses: + "200": + description: OK + headers: + Content-Type: + schema: + type: string + example: application/jwt + enum: + - application/jwt + content: + application/jwt: + schema: + type: string + example: eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJjdXMiOiJVQUFBQUEiLCJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJiaXJ0aGRhdGUiOiIyMDAwLTAyLTIwIiwicm9sZSI6IkFDQ09VTlRBTlQsIE1BTkFHRVIiLCJnZW5kZXIiOiJNQUxFIiwiaWRlbnRpdHlfZG9jdW1lbnRfbmFtZSI6ItCf0LDRgdC_0L7RgNGCINCz0YDQsNC20LTQsNC90LjQvdCwINCg0KQiLCJpZGVudGl0eV9kb2N1bWVudF9udW1iZXIiOjIyMjIyMiwiaXNzIjoiaHR0cHM6XC9cL2JhYXMuYWxmYWJhbmsucnUiLCJpbm4iOjc0MTUxMTExMjIyMiwiZWlvIjp0cnVlLCJnaXZlbl9uYW1lIjoi0KLQtdGB0YIiLCJtaWRkbGVfbmFtZSI6ItCi0LXRgdGC0L7QstC40YciLCJhY3VzIjoiWEFBQUFBIiwiaWRlbnRpdHlfZG9jdW1lbnRfc2VyaWVzIjoxMTExLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY2xjIjoiWEFBQUExIiwidXBkYXRlZF9hdCI6IjIwMjItMDEtMjAiLCJuYW1lIjoi0KLQtdGB0YLQvtCyINCi0LXRgdGCINCi0LXRgdGC0L7QstC40YciLCJwaG9uZV9udW1iZXIiOjc5MTkxMTEyMjMzLCJjbGMiOiJVQUFBQTEiLCJmYW1pbHlfbmFtZSI6ItCi0LXRgdGC0L7QsiIsImVtYWlsIjoiZW1haWxAZW1haWwucnUifQ.WVr5xkQSEGqpPXN3aIo0zHZLDL0vvtxEEQ83BrgJo7l0BjjALeGDRYENF2bL8j3n1pXRnduiBQcYNV6teBhESI8V_8kd7Kh7LTePkJWadPSvD__KskC69b4XZ-zN-IQ73NmAcBDStnnhSXGKL6xhdRy-TGiAoKPsRWiDVntsDlpCQNHAt3tJk8q_SQS4S1k6qju9eJ2GFkgmd6z8rR2vaBykaOF0K61ltksw6YgXhuek3OlYkqIAivyKYl59uio8zMpJk-YrPlmawwmvWPF0vKhaLj8Mvn4mVMsVSfuVVKP2ksHG0MAlWpO3Sh9GoKO4d6TQplJ4vgIIeNx-44npqw + "400": + description: BAD REQUEST + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfoError' + "401": + description: UNAUTHORIZED + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfoError' + "403": + description: FORBIDDEN + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfoError' + "404": + description: NOT FOUND + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: INTERNAL SERVER ERROR + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfoError' + "503": + description: Сервер временно недоступен + /clients/{clientId}/client-secret: + post: + tags: + - OIDC + summary: Получение Client Secret + description: Получение Client Secret + parameters: + - name: clientId + in: path + description: Идентификатор партнерского сервиса + required: true + schema: + type: string + format: uuid + example: 0cee0683-85ae-49f2-a63d-29f97aad1911 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClientSecretResponse' + "400": + description: BAD REQUEST + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/ClientSecretError' + "404": + description: NOT FOUND + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/ClientSecretError' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: INTERNAL SERVER ERROR + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/ClientSecretError' + "503": + description: Сервер временно недоступен + /revoke: + post: + tags: + - OIDC + summary: Отзыв токена + description: Отзыв токена + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/RevokeRequest' + required: true + responses: + "200": + description: OK + "400": + description: BAD REQUEST + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/RevokeError' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: INTERNAL SERVER ERROR + headers: + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/RevokeError' + "503": + description: Сервер временно недоступен + /v1/customer-info: + get: + tags: + - Customer-info + summary: Получение профиля организации + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ClientInfo' + examples: + example: + $ref: '#/components/examples/getCustomerInfo' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /statement/transactions: + get: + tags: + - Transactions + summary: Получение операций по счетам + parameters: + - name: accountNumber + in: query + description: Номер расчетного счета + required: true + schema: + pattern: "\\d{20}" + type: string + example: 40702810701300000761 + - name: statementDate + in: query + description: Дата исполнения операции + required: true + schema: + type: string + format: date + example: 2022-01-13 + - name: page + in: query + description: Номер запрашиваемой страницы + required: false + schema: + minimum: 1 + type: integer + default: 1 + example: 2 + - name: curFormat + in: query + description: Формат операции по валютному счету + required: false + schema: + pattern: ^(curTransfer|swiftTransfer)$ + type: string + example: curTransfer + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/Statement' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v2/accounts/{accountNumber}/transactions/1C: + get: + tags: + - Transactions + summary: Получение операций по счетам в формате 1С + parameters: + - name: accountNumber + in: path + description: Номер расчетного счета + required: true + schema: + pattern: "\\d{20}" + type: string + example: 40702810701300000761 + - name: executeDate + in: query + description: Дата исполнения + required: true + schema: + type: string + format: date + example: 2022-01-20 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: true + schema: + minimum: 0 + type: integer + default: 0 + example: 0 + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + minimum: 1 + type: integer + default: 10 + example: 1000 + - name: X-Response-ChannelSecurity + in: header + description: "Тип защиты канала в ответе (SIGNATURE - только подпись, ENCRYPTION\ + \ - подпись и шифрование)" + required: false + schema: + type: string + example: SIGNATURE + responses: + "200": + description: OK + headers: + X-TraceId: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + X-Pagination-Limit: + description: Количество записей на одной странице + schema: + type: integer + example: 1000 + X-Pagination-Offset: + description: "Количество записей в списке, которые были пропущены" + schema: + type: integer + example: 0 + X-Pagination-Total-Count: + description: Общее количество записей + schema: + type: integer + example: 10000 + X-SymmetricKey: + description: Симметричный ключ + schema: + type: string + example: AGpWUZip/ita8COYlDotThRde4Opx3FNs3/l4Q3ncVcYN4Yuid6Npx3USq5RE9rLiL/G7VQcJkmsfIkwW/CfaRo9MjclwUq/l3GSwUTBSf+5lsiE5WrCobzIDoVYLL6n2Q+wWC23jobEM+7aFlDRR3lmlXBTouR98I2nNEg2Dtuo8m0/SrwWyADpDI680Vey4Uki5asraVR50zRh0D61mgesIxARHHkC2OvjmsC4AJd2cyrEo/uAFICZNcc/v8jFpHXgSL+Y7IiyJsMusz6uh15oU2ytBQkyUYUn5r6/r+e1z5uTiC9JLcm7tEzSEuzmw4FUF4p9WtQm30j+4GQUQQ== + X-InitializationVector: + description: Вектор инициализации + schema: + type: string + example: BX4RGLMrWXhHZaoSfkfZLMu/pO5K81sJWIsDoabUBiymhA6xZy7LNJWkUGpWndaCGgLn5l4csmvzDp0+c9kHgDbObXfhbw6wKOGf3wB8dYyexhau5krW/40EEukO0O3d/IB0UsXiE3mXA0/G52vQTxi+V3L+l1+g4rsipQhhY8yzliYZ7XrkvGnri4plnB8jX1EFfMiE6Q3QdmAGAz5fLY0oDTOi8dGgH7XkURtPX3VsuYFBO7Glxvr6PeHSG7Xnl5qAbayKHg3lAW9u7YEwvRd+OF+y7xlp9f2j5xCBhw0LXt+RTMTBEvSHqTYpY+vgYnKW/J79ExL2WLsbc/Y++A==HgDbObXfhbw6wKOGf3wB8dYyexhau5krW/40EEukO0O3d/IB0UsXiE3mXA0/G52vQTxi+V3L+l1+g4rsipQhhY8yzliYZ7XrkvGnri4plnB8jX1EFfMiE6Q3QdmAGAz5fLY0oDTOi8dGgH7XkURtPX3VsuYFBO7Glxvr6PeHSG7Xnl5qAbayKHg3lAW9u7YEwvRd+OF+y7xlp9f2j5xCBhw0LXt+RTMTBEvSHqTYpY+vgYnKW/J79ExL2WLsbc/Y++A== + content: + application/xml: + schema: + $ref: '#/components/schemas/ResponseSigned' + examples: + Response: + $ref: '#/components/examples/Response' + ResponseSigned: + $ref: '#/components/examples/ResponseSigned' + Signed and Encrypted: + $ref: '#/components/examples/ResponseSignedEncrypted' + "400": + description: Неверные входные параметры запроса + content: + application/xml: + schema: + $ref: '#/components/schemas/ErrorBadRequestXML' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/xml: + schema: + $ref: '#/components/schemas/ErrorUnauthorizedXML' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/xml: + schema: + $ref: '#/components/schemas/ErrorScopeXML' + "404": + description: Эндпоинт не найден или неактивен + content: + application/xml: + schema: + $ref: '#/components/schemas/ErrorNotFoundXML' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/xml: + schema: + $ref: '#/components/schemas/ErrorInternalXML' + "503": + description: Сервер временно недоступен + /accounts/{accountNumber}/transactions/MT940: + get: + tags: + - Transactions + summary: Получение операций по счетам в формате MT940 + parameters: + - name: accountNumber + in: path + description: Номер расчетного счета + required: true + schema: + pattern: "\\d{20}" + type: string + example: 40702810701300000761 + - name: executeDate + in: query + description: Дата исполнения + required: true + schema: + type: string + format: date + example: 2022-01-20 + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + minimum: 1 + type: integer + default: 10 + example: 1000 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + default: 0 + example: 0 + responses: + "200": + description: OK + content: + text/plain: + schema: + $ref: '#/components/schemas/StatementMT940' + "400": + description: Неверные входные параметры запроса + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorBadRequestText' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorUnauthorizedText' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorScopeText' + "404": + description: Эндпоинт не найден или неактивен + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorNotFoundText' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + text/plain: + schema: + $ref: '#/components/schemas/ErrorInternalText' + "503": + description: Сервер временно недоступен + /statement/summary: + get: + tags: + - Transactions + summary: Получение информации об оборотах + parameters: + - name: accountNumber + in: query + description: Номер расчетного счета + required: true + schema: + pattern: "\\d{20}" + type: string + example: 40702810701300000761 + - name: statementDate + in: query + description: Дата исполнения операции + required: true + schema: + type: string + format: date + example: 2022-01-13 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/StatementSummary' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /gd/v1/accounts/{accountNumber}/status: + get: + tags: + - Transactions + summary: Получение информации о действующем счете в Банке + parameters: + - name: accountNumber + in: path + description: Номер счета + required: true + schema: + pattern: "^\\d{20}$" + type: string + example: "40817810210210066268" + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/_gd_v1_accounts__accountNumber__status_get_200_response' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + example: + error: invalid_request + error_description: Parameter accountNumber is not valid + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + example: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + example: + error: insufficient_scope + error_description: The request requires higher privileges than provided + by the access token + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + example: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + /jp/v1/correspondent-accounts/{accountNumber}/transactions: + get: + tags: + - Transactions + summary: Получение операций по корреспондентским счетам + parameters: + - name: accountNumber + in: path + description: Номер корреспондентского расчетного счета + required: true + schema: + type: string + example: 30102810701300000761 + - name: executeDate + in: query + description: Дата исполнения + required: true + schema: + type: string + format: date + example: 2022-01-20 + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + type: integer + example: 1000 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + type: integer + example: 0 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/CorrespondentStatement' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/accounts/{accountNumber}/transactions/files/requests: + post: + tags: + - Transactions + summary: Создание заявки на формирование файла выписки + parameters: + - name: accountNumber + in: path + description: Номер расчетного счета + required: true + schema: + type: string + example: 40702810701300000761 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestsCreateFileTransaction' + responses: + "201": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/RequestsCreateFileTransaction' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/accounts/transactions/files/requests/{requestId}: + get: + tags: + - Transactions + summary: Получение информации по заявке на формирование файла выписки + parameters: + - name: requestId + in: path + description: Идентификатор запроса + required: true + schema: + type: string + example: 67e50b09-a203-4119-86cb-647d06a803a0 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseGetFileTransaction' + examples: + example: + $ref: '#/components/examples/ResponseGetFileTransaction' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/open-banking/v1.3/accounts: + get: + tags: + - Transactions + summary: Получение списка счетов Альфа-Банка в формате OpenBanking + description: | + Конечная точка позволяет СПИУ получать полный список счетов Альфа-Банка и их + идентификаторы (accountId), которые были авторизованы Пользователем на + стороне ППИУ + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + responses: + "200": + description: "Полный список счетов (с идентификаторами accountId), котор\ + ые были авторизованы Пользователем на стороне ППИУ" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/AccountResponse' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/external/accounts: + get: + tags: + - Transactions + summary: Получение списка счетов других банков в формате OpenBanking + description: | + Конечная точка позволяет получать полный список счетов пользователей в других банках и их + идентификаторы (accountId) в формате АФТ + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + responses: + "200": + description: "Полный список счетов (с идентификаторами accountId), котор\ + ые были авторизованы Пользователем на стороне ППИУ" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/AccountResponse' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/accounts/{accountId}/statements: + get: + tags: + - Transactions + summary: Получение выписки по идентификатору счета Альфа-Банка в формате OpenBanking + description: "Конечная точка позволяет СПИУ получать выписки по идентификато\ + ру счета Альфа-Банка, который предоставляется при вызове конечной точки GET\ + \ /accounts, в режиме онлайн" + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + - name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + responses: + "200": + description: Ответ получения выписки по идентификатору выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/StatementResponse' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/statements: + post: + tags: + - Transactions + summary: Создание ресурса выписки Альфа-Банка в формате OpenBanking + description: "Конечная точка позволяет СПИУ создать ресурс выписки по иденти\ + фикатору счета Альфа-Банка, accountId, который предоставляется при вызове\ + \ конечной точки GET /accounts" + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: x-idempotency-key + in: header + description: Уникальный идентификатор запроса для поддержки идемпотентности. + Обязательно для запросов POST к конечным точкам идемпотентного ресурса. + Для других запросов не указывается. + required: true + schema: + type: string + format: uuid + - name: x-jws-signature + in: header + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/StatementInitRequest' + examples: + Response: + $ref: '#/components/examples/RequestCreateStatements' + required: true + responses: + "201": + description: Индентификатор выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + x-jws-signature: + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/StatementInitResponse' + example: + Data: + Statement: + statementId: this-is-a-slug-format-statement-id + accountId: this-is-a-slug-format-account-id + fromBookingDateTime: 2019-09-15T00:00:00+00:00 + toBookingDateTime: 2019-12-15T00:00:00+00:00 + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/statements/{statementId}: + get: + tags: + - Transactions + summary: Получение выписки Альфа-Банка по идентификатору в формате OpenBanking + description: Конечная точка позволяет СПИУ получать выписку из Альфа-Банка по + идентификатору + parameters: + - name: statementId + in: path + description: Идентификатор выписки + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: 9b23e27e-f4f8-4cab-9b80-aaa008d4330c + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + responses: + "200": + description: Ответ получения выписки по идентификатору выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/StatementResponse' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/external/statements: + post: + tags: + - Transactions + summary: Создание ресурса выписки банка-партнера в формате OpenBanking + description: "Конечная точка позволяет СПИУ создать ресурс выписки из банка\ + -партнера по идентификатору счета accountId, который предоставляется при в\ + ызове конечной точки GET /accounts" + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: x-idempotency-key + in: header + description: Уникальный идентификатор запроса для поддержки идемпотентности. + Обязательно для запросов POST к конечным точкам идемпотентного ресурса. + Для других запросов не указывается. + required: true + schema: + type: string + format: uuid + - name: x-jws-signature + in: header + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/StatementInitRequest' + examples: + Response: + $ref: '#/components/examples/RequestCreateStatements' + required: true + responses: + "201": + description: Индентификатор выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + x-jws-signature: + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/StatementInitResponse' + example: + Data: + Statement: + statementId: this-is-a-slug-format-statement-id + accountId: this-is-a-slug-format-account-id + fromBookingDateTime: 2019-09-15T00:00:00+00:00 + toBookingDateTime: 2019-12-15T00:00:00+00:00 + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/open-banking/v1.3/external/statements/{statementId}: + get: + tags: + - Transactions + summary: Получение выписки по идентификатору банка-партнера в формате OpenBanking + description: Конечная точка позволяет СПИУ получать выписку из банка-партнера + по идентификатору выписки + parameters: + - name: statementId + in: path + description: Идентификатор выписки + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: 9b23e27e-f4f8-4cab-9b80-aaa008d4330c + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значени\ + е предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Нап\ + ример, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + - name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент под\ + ключен к Стороннему Поставщику (авторизован в приложении Стороннего Пост\ + авщика)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + - name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который\ + \ использует Пользователь. Сторонний Поставщик может заполнить это поле\ + \ значением типа устройства (user-agent), указанным Пользователем. Если\ + \ Пользователь использует мобильное приложение Стороннего Поставщика, Ст\ + оронний Поставщик проверяет, что строка типа устройства (user-agent) отл\ + ичается от строки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + responses: + "200": + description: Ответ получения выписки по идентификатору выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/StatementResponse' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с п\ + омощью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406": + description: "Запрос содержал параметр заголовка Accept, отличный от раз\ + решенных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501": + description: "Сторонний поставщик не поддерживает функции, необходимые д\ + ля выполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении + непредвиденной ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + /jp/v3/signature/dn: + get: + tags: + - Signature + summary: Получение DN пользователя + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseDN' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/dn/file: + get: + tags: + - Signature + summary: Получение DN пользователя файлом в формате .cnf + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + text/plain: + schema: + $ref: '#/components/schemas/ResponseDNcnf' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/requests/issue: + post: + tags: + - Signature + summary: Заявка на выпуск RSA-сертификата + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestIssueRSACertificate' + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/postIssueResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/requests/{id}/operations: + post: + tags: + - Signature + summary: Отправка заявки на подпись + parameters: + - name: id + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 62550ef50163785f2222707e + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestPostOperations' + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponsePostOperations' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/requests/operations/{id}: + put: + tags: + - Signature + summary: Подписание заявки c помощью кода из СМС + parameters: + - name: id + in: path + description: Идентификатор операции + required: true + schema: + type: string + example: 2629a563-3c82-44a2-a4f5-67b79e44cbea + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestPutOperations' + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponsePutOperations' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/requests/{id}: + get: + tags: + - Signature + summary: Получение данных заявки + parameters: + - name: id + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 62550ef50163785f2222707e + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/RequestData' + examples: + example: + $ref: '#/components/examples/getIssueResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/{id}: + get: + tags: + - Signature + summary: Получение RSA-сертификата + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + schema: + type: string + example: 62552f2457595f1652c4b179 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/RSACertificate' + examples: + example: + $ref: '#/components/examples/getRsaResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/{id}/requests/activation: + post: + tags: + - Signature + summary: Заявка на активацию RSA-сертификата + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + schema: + type: string + example: 62552f2457595f1652c4b179 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/postActivateResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/sign-settings: + put: + tags: + - Signature + summary: Заявка на изменение текущего способа подписи + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SignSettings' + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/putSignSettingResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/{id}/requests/revocation: + post: + tags: + - Signature + summary: Заявка на отзыв RSA-сертификата + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + schema: + type: string + example: 62552f2457595f1652c4b179 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/postRevocationResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/{id}/requests/switch: + post: + tags: + - Signature + summary: Заявка на переключение RSA-сертификата + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + schema: + type: string + example: 62552f2457595f1652c4b179 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/postSwitchResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/rsa-certificates/{id}/requests/reissue: + post: + tags: + - Signature + summary: Заявка на перевыпуск RSA-сертификата + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + schema: + type: string + example: 62552f2457595f1652c4b179 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestReissueRSACertificate' + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponesIssueRSACertificate' + examples: + example: + $ref: '#/components/examples/postReissueResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/qes/requests: + post: + tags: + - Signature + summary: Заявка на подключение КЭП + operationId: qesRequestsEnablePost + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/EnableQesResponse' + examples: + example: + $ref: '#/components/examples/enableQesResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/qes/requests/{id}: + post: + tags: + - Signature + summary: Отправка заявки на подключение КЭП на подпись + operationId: qesRequestsPost + parameters: + - name: id + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 63160a37e27edd0c316567a6 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SendRequestQes' + examples: + example: + $ref: '#/components/examples/qesRequestsPostRequestExample' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SendRequestQesResponse' + examples: + example: + $ref: '#/components/examples/qesRequestsPostResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + patch: + tags: + - Signature + summary: Подписание заявки с помощью КЭП + operationId: qesRequestsPatch + parameters: + - name: id + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 63160a37e27edd0c316567a6 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SignRequestQes' + examples: + example: + $ref: '#/components/examples/qesRequestsPatchRequestExample' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SignRequestQesResponse' + examples: + example: + $ref: '#/components/examples/qesRequestsPatchResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/powers-of-attorney/requests: + post: + tags: + - Signature + summary: Регистрация МЧД в банке + operationId: poaRequestsPost + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DownloadPoaRequest' + examples: + example: + $ref: '#/components/examples/downloadPoaRequestExample' + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/DownloadPoaResponse' + examples: + example: + $ref: '#/components/examples/downloadPoaResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/powers-of-attorney/requests/{id}/status: + get: + tags: + - Signature + summary: Получение статуса регистрации МЧД + operationId: poaRequestsStatusGet + parameters: + - name: id + in: path + description: Идентификатор запроса в системе МЧД + required: true + schema: + type: string + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetDownloadStatus' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v3/signature/powers-of-attorney/requests/{id}: + get: + tags: + - Signature + summary: Скачивание файла машиночитаемой доверенности + operationId: poaRequestsDownloadGet + parameters: + - name: id + in: path + description: Идентификатор запроса в системе МЧД + required: true + schema: + type: string + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + responses: + "200": + description: OK + headers: + Content-Type: + required: true + schema: + type: string + example: application/pdf + Content-Disposition: + required: false + schema: + type: string + example: attachment; filename=poa-e386c9e2-b37b-484d-a691-38a74e8d3fbf.pdf + content: + application/pdf: + schema: + type: string + format: binary + application/zip: + schema: + type: string + format: binary + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v2/payments: + post: + tags: + - Payments + summary: Создание рублёвого платёжного поручения + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Payment' + examples: + example: + $ref: '#/components/examples/createPaymentRequest' + responses: + "201": + description: Документ создан + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/Payment' + examples: + example: + $ref: '#/components/examples/createPaymentResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v2/payments/{externalId}/state: + get: + tags: + - Payments + summary: Получение статуса поручения + parameters: + - name: externalId + in: path + description: "Идентификатор документа, присвоенный партнером (UUID)" + required: true + schema: + type: string + format: uuid + responses: + "200": + description: OK + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentDocState' + examples: + example: + $ref: '#/components/examples/getPaymentStatusResponse' + "400": + description: Неверный формат запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Платёжный документ не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + patch: + tags: + - Payments + summary: Обновление статуса платёжного поручения + parameters: + - name: externalId + in: path + description: "Идентификатор документа, присвоенный партнером (UUID)" + required: true + schema: + type: string + format: uuid + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchPaymentStateRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentDocState' + examples: + example: + $ref: '#/components/examples/patchPaymentStateResponse' + "400": + description: Неверный формат запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Платёжный документ не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /payments/{externalId}: + get: + tags: + - Payments + summary: Получение атрибутов поручения + parameters: + - name: externalId + in: path + description: "Идентификатор документа, присвоенный партнером (UUID)" + required: true + schema: + type: string + format: uuid + responses: + "200": + description: OK + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/Payment' + examples: + example: + $ref: '#/components/examples/createPaymentResponse' + "400": + description: Неверный формат запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Платежный документ не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /payments/{externalId}/print-form: + get: + tags: + - Payments + summary: Получение печатной формы платёжного поручения + parameters: + - name: externalId + in: path + description: "Идентификатор документа, присвоенный партнером (UUID)" + required: true + schema: + type: string + format: uuid + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + responses: + "200": + description: Успешный результат + headers: + Content-Type: + required: true + schema: + type: string + example: application/json + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPrintForm' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /payments/{externalId}/print-form/download: + get: + tags: + - Payments + summary: Получение печатной формы платёжного поручения в PDF + parameters: + - name: externalId + in: path + description: "Идентификатор документа, присвоенный партнером (UUID)" + required: true + schema: + type: string + format: uuid + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + responses: + "200": + description: Успешный результат + headers: + Content-Type: + required: true + schema: + type: string + example: application/pdf + Content-Disposition: + required: false + schema: + type: string + example: attachment; filename*=UTF-8'%D0%9F%D0%BB%D0%B0%D1%82%D0%B5%D0%B6%D0%BD%D0%BE%D0%B5_%D0%BF%D0%BE%D1%80%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%E2%84%96657073_11.10.2022.pdf + content: + application/pdf: + schema: + type: string + format: byte + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v2/payments/count: + get: + tags: + - Payments + summary: "Получение количества рублёвых платежей, созданных через канал Alfa\ + \ API" + parameters: + - name: status + in: query + description: Статус обработки документа + required: true + schema: + $ref: '#/components/schemas/Status' + example: SIGNED + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentsCountResponse' + "400": + description: Неверный формат запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /payments/from-invoice: + post: + tags: + - Payments + summary: Выставление счета клиенту для Альфа-Банка + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InvoiceRequest' + examples: + example: + $ref: '#/components/examples/fromInvoiceRequest' + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/InvoiceResponse' + examples: + example: + $ref: '#/components/examples/fromInvoiceResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v2/payments/from-invoice-budget: + post: + tags: + - Payments + summary: Выставление счета на оплату в бюджет + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InvoiceBudgetRequest' + examples: + example: + $ref: '#/components/examples/fromInvoiceBudgetRequest' + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/InvoiceBudgetResponse' + examples: + example: + $ref: '#/components/examples/fromInvoiceBudgetResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/registries: + post: + tags: + - PaymentRegistries + summary: Создание реестра рублёвых платежей + operationId: createRegistry + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegistryPaymentsRequest' + examples: + example: + $ref: '#/components/examples/CreateRegistryRequest' + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/RegistryPaymentsResponse' + examples: + example: + $ref: '#/components/examples/CreateRegistryResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + /jp/v1/registries/{registryId}: + get: + tags: + - PaymentRegistries + summary: Получение данных реестра рублёвых платежей + operationId: getRegistry + parameters: + - name: registryId + in: path + description: Идентификатор реестра + required: true + schema: + type: string + example: U102702240001208 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Registry' + examples: + example: + $ref: '#/components/examples/GetRegistryResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + patch: + tags: + - PaymentRegistries + summary: Обновление статуса реестра рублёвых платежей + operationId: updateRegistryStatus + parameters: + - name: registryId + in: path + description: "Идентификатор реестра (U102702240001209 со статусом ON_SIGNING,\ + \ U102702240001210 - PROCESSING)" + required: true + schema: + type: string + example: U102702240001209 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateRegistryStatusRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RegistryWithContent' + examples: + example: + $ref: '#/components/examples/UpdateRegistryStatusResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + /jp/v1/registries/{registryId}/payments: + get: + tags: + - PaymentRegistries + summary: Получение списка рублёвых платежей в реестре + operationId: getRegistryPayments + parameters: + - name: registryId + in: path + description: Идентификатор реестра + required: true + schema: + type: string + example: U102702240001208 + - name: status + in: query + description: | + Статусы платежей для фильтрации: + * `DRAFT` - Черновик; + * `ON_SIGNING` - На подпись; + * `TO_BE_SEND` - К отправке; + * `PROCESSING` - На исполнении; + * `DONE` - Исполнен; + * `REJECTED` - Не исполнен; + * `DECLINED` - Отклонён; + * `DELETED` - Удалён + required: false + schema: + type: array + items: + type: string + enum: + - DRAFT + - ON_SIGNING + - TO_BE_SEND + - PROCESSING + - DONE + - REJECTED + - DECLINED + - DELETED + example: ?status=DRAFT&status=DONE + - name: fromDate + in: query + description: Дата начала периода + required: false + schema: + type: string + format: date + example: 2024-08-01 + - name: toDate + in: query + description: Дата окончания периода + required: false + schema: + type: string + format: date + example: 2024-09-01 + - name: sort + in: query + description: "Сортировка результатов поиска. Возможные значения: 'number',\ + \ 'date', 'amount'." + required: false + schema: + type: string + example: "amount,asc" + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + default: 100 + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetRegistryPaymentsResponse' + examples: + example: + $ref: '#/components/examples/GetRegistryPaymentsResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + /jp/v1/registries/{registryId}/signatures: + post: + tags: + - PaymentRegistries + summary: Наложение подписей на реестр рублёвых платежей + operationId: signRegistry + parameters: + - name: registryId + in: path + description: Идентификатор реестра + required: true + schema: + type: string + example: U102702240001208 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegistrySignRequest' + examples: + example: + $ref: '#/components/examples/SignRegistryRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RegistrySignResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + /jp/v1/registries/{registryId}/signatures/{signatureId}: + get: + tags: + - PaymentRegistries + summary: Получение результата наложения подписей + operationId: getSignResult + parameters: + - name: registryId + in: path + description: Идентификатор реестра + required: true + schema: + type: string + example: U102702240001208 + - name: signatureId + in: path + description: Идентификатор запроса на подписание + required: true + schema: + type: string + example: 0937b8b1-b226-45f3-b93e-7ba9008db79a + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetRegistrySignResponse' + examples: + exampleRsa: + $ref: '#/components/examples/GetSignResultRsa' + examplePartially: + $ref: '#/components/examples/GetSignResultPartially' + exampleQes: + $ref: '#/components/examples/GetSignResultQes' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Too Many Requests + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Service Unavailable + /build-projects: + get: + tags: + - Escrow-accounts + summary: Получение списка объектов строительства застройщика + responses: + "200": + description: Проекты строительства + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/EscrowBuildProject' + examples: + example: + $ref: '#/components/examples/getBuildProjectsResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /escrow-orders: + get: + tags: + - Escrow-accounts + summary: Получение списка заявок застройщика + parameters: + - name: filterFromDate + in: query + description: Дата начала периода создания заявки + required: true + schema: + type: string + format: date + example: 2020-10-23 + - name: filterToDate + in: query + description: Дата окончания периода создания заявки + required: true + schema: + type: string + format: date + example: 2020-10-23 + - name: filterStatuses + in: query + required: false + schema: + type: array + items: + $ref: '#/components/schemas/FilterStatusesV0' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + type: integer + example: 10 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + type: integer + example: 2 + responses: + "200": + description: Список заявок застройщика + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: b57610640b625736 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/GetEscrowOrdersV0Response' + examples: + example: + $ref: '#/components/examples/getEscrowOrdersV0ResponseExample' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - Escrow-accounts + summary: Создание заявки на резервирование счета эскроу + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEscrowOrderRequest' + examples: + example: + $ref: '#/components/examples/postEscrowOrdersRequestExample' + required: true + responses: + "200": + description: Заявка на резервирование счета эскроу успешно создана + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEscrowOrderResponse' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEscrowOrderErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-orders: + get: + tags: + - Escrow-accounts + summary: Получение списка заявок застройщика + parameters: + - name: filterFromDate + in: query + description: Дата начала периода создания заявки + required: true + schema: + type: string + format: date + example: 2020-10-23 + - name: filterToDate + in: query + description: Дата окончания периода создания заявки + required: true + schema: + type: string + format: date + example: 2020-10-23 + - name: filterStatuses + in: query + required: false + schema: + type: array + items: + $ref: '#/components/schemas/FilterStatusesV1' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + type: integer + example: 10 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + type: integer + example: 2 + responses: + "200": + description: Список заявок застройщика + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: b57610640b625736 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/GetEscrowOrdersV1Response' + examples: + example: + $ref: '#/components/examples/getEscrowOrdersV1ResponseExample' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /escrow-orders/{referenceID}: + get: + tags: + - Escrow-accounts + summary: Получение детальной информации по заявке на резервирование счета эскроу + parameters: + - name: referenceID + in: path + description: Номер заявки на резервирование счета эскроу + required: true + schema: + type: string + example: EA10808220000061 + responses: + "200": + description: Детальная информация по заявке на резервирование счета эскроу + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/GetEscrowOrderV0Response' + examples: + example: + $ref: '#/components/examples/getEscrowOrderV0ResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + delete: + tags: + - Escrow-accounts + summary: Удаление заявки в статусе черновик + parameters: + - name: referenceID + in: path + description: Номер заявки на резервирование счета эскроу + required: true + schema: + type: string + example: EA10808220000061 + responses: + "204": + description: Заявка в статусе черновик успешно удалена + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-orders/{referenceID}: + get: + tags: + - Escrow-accounts + summary: Получение детальной информации по заявке на резервирование счета эскроу + parameters: + - name: referenceID + in: path + description: Номер заявки на резервирование счета эскроу + required: true + schema: + type: string + example: EA10808220000061 + responses: + "200": + description: Детальная информация по заявке на резервирование счета эскроу + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/GetEscrowOrderV1Response' + examples: + example: + $ref: '#/components/examples/getEscrowOrderV1ResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-orders/{referenceID}/cancel: + post: + tags: + - Escrow-accounts + summary: Отмена заявки на резервирование счета эскроу + parameters: + - name: referenceID + in: path + description: Номер заявки на резервирование счета эскроу + required: true + schema: + type: string + example: EA10808220000061 + responses: + "200": + description: Успешная отмена заявки + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/CancelOrderV1Response' + examples: + example: + $ref: '#/components/examples/escrowOrderCancelV1ResponseExample' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /escrow-orders/{referenceID}/execute: + patch: + tags: + - Escrow-accounts + summary: Отправка признака регистрации ДДУ в Росреестре + parameters: + - name: referenceID + in: path + description: Номер заявки на резервирование счета эскроу + required: true + schema: + type: string + example: EA10808220000061 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ExecuteEscrowOrderRequest' + examples: + example: + $ref: '#/components/examples/postExecuteRequestExample' + required: true + responses: + "204": + description: Заявка переведена в статус Исполнено + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-orders-full: + post: + tags: + - Escrow-accounts + summary: Создание заявки с расширенными параметрами на резервирование счета + эскроу + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFullOrderV1Request' + examples: + example: + $ref: '#/components/examples/postEscrowOrdersFullRequestExample' + required: true + responses: + "200": + description: Заявка на резервирование счета эскроу успешно создана + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFullOrderV1Response' + examples: + example: + $ref: '#/components/examples/postEscrowOrdersFullResponseExample' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEscrowOrderErrorConflict' + "429": + description: Слишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-reports/developers/build-projects: + get: + tags: + - Escrow-accounts + summary: Получение списка объектов и этапов строительства застройщика + responses: + "200": + description: Список заявок застройщика + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: b57610640b625736 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/EscrowReportsBuildProjectsV1Response' + examples: + example: + $ref: '#/components/examples/getEscrowReportsV1ResponseExample' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/escrow-reports: + post: + tags: + - Escrow-accounts + summary: Генерация отчета по счетам эскроу в соответствии с переданной фильтрацией + parameters: + - name: limit + in: query + description: Количество объектов на одной странице + required: true + schema: + type: integer + example: 10 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: true + schema: + type: integer + example: 2 + - name: periodFrom + in: query + description: Начальная дата периода для формирования отчета + required: true + schema: + type: string + example: 2024-11-11T00:00:00.000Z + - name: periodTo + in: query + description: Конечная дата периода для формирования отчета + required: true + schema: + type: string + example: 2024-11-11T00:00:00.000Z + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1Request' + examples: + example: + $ref: '#/components/examples/postEscrowReportsV1RequestExample' + required: true + responses: + "200": + description: Сформированный отчёт в формате json + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: c57610640b625732 + Content-Type: + schema: + type: string + example: application/json + enum: + - application/json + content: + application/json: + schema: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1Response' + examples: + example: + $ref: '#/components/examples/postEscrowReportsV1ResponseExample' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEscrowOrderErrorConflict' + "429": + description: Слишком много запросов в заданный период времени + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /smart-loans/jp/v1/loan-applications: + post: + tags: + - Loans + summary: Отправка данных для скоринга и создания черновика заявки + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ScoringAny' + examples: + example: + $ref: '#/components/examples/ScoringAnyResponseExample' + required: true + responses: + "200": + description: Успешное создание черновика заявки + content: + application/json: + schema: + $ref: '#/components/schemas/ScoringAnyResponse' + "400": + description: Отсутствие обязательных параметров + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Ошибка в JWT (просрочен, отозван и т.д.)" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервера + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /smart-loans/jp/v1/loan-applications/{dealId}/status: + get: + tags: + - Loans + summary: Запрос информации о статусе кредитной заявки + parameters: + - name: dealId + in: path + description: Уникальный идентификатор заявки (UUIDv4) + required: true + schema: + pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" + type: string + format: uuid + example: aef72949-0e9a-41bf-a11d-abbbcccf1e22 + responses: + "200": + description: Ответ с информацией о статусе + content: + application/json: + schema: + $ref: '#/components/schemas/StatusResponse' + "400": + description: Отсутствие обязательных параметров + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Ошибка в JWT (просрочен, отозван и т.д.)" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервера + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/bonus-numbers: + summary: Ресурс для получение бонусных номеров карт клиента + description: Получение бонусных номеров карт клиента + get: + tags: + - BonusNumbers + summary: Получение бонусных номеров карт клиента + operationId: getBonusNumbers + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BonusNumbersResponse' + examples: + example: + $ref: '#/components/examples/BonusNumbersResponse' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/user-compliance: + summary: Проверка актуальности сведений + description: Метод возвращает результат проверки актуальности сведений клиента. + get: + tags: + - UserCompliance + summary: Получение результатов проверок актуальности сведений клиента + operationId: getUserCompliance + responses: + "200": + description: Успешный запрос. Возвращает результат проверки актуальности + сведений клиента. + content: + application/json: + schema: + $ref: '#/components/schemas/UserComplianceGetResponse' + examples: + positive: + $ref: '#/components/examples/successGetUserCompliancePositive' + negative: + $ref: '#/components/examples/successGetUserComplianceNegative' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/user-compliance/operations: + post: + tags: + - UserCompliance + summary: Инициация асинхронной проверки compliance + description: | + Принимает запрос на проверку пользователя и возвращает operationId. Результат проверки будет отправлен по переданному callbackUri. + operationId: initiateUserCompliance + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ComplianceRequest' + required: true + responses: + "202": + description: Запрос принят к асинхронной обработке. Возвращает operationId. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationResponse' + examples: + success: + $ref: '#/components/examples/OperationResponseSuccess' + "400": + description: Неверные или отсутствующие параметры или тело запроса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при приёме запроса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен. + /pp/v1/user-compliance/operations/simplified: + post: + tags: + - UserCompliance + summary: Инициация асинхронной упрощенной проверки compliance + description: | + Принимает запрос на проверку пользователя и возвращает operationId. Результат проверки будет отправлен по переданному callbackUri. + operationId: initiateUserCompliance + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ComplianceRequest' + required: true + responses: + "202": + description: Запрос принят к асинхронной обработке. Возвращает operationId. + content: + application/json: + schema: + $ref: '#/components/schemas/OperationResponse_1' + examples: + success: + $ref: '#/components/examples/OperationResponseSuccess' + "400": + description: Неверные или отсутствующие параметры или тело запроса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при приёме запроса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен. + /v2/webhooks: + get: + tags: + - Webhooks + summary: Получение списка вебхуков + parameters: + - name: object + in: query + description: Объект + required: true + schema: + type: string + example: ul_transaction_default + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + type: integer + example: 1000 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + type: integer + example: 0 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponeWebhooks' + examples: + example: + $ref: '#/components/examples/ResponeWebhooks' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - Webhooks + summary: Создание вебхука + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestPostWebhook' + examples: + example: + $ref: '#/components/examples/RequestPostWebhook' + responses: + "201": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponeWebhook' + examples: + example: + $ref: '#/components/examples/ResponeWebhook' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /v2/webhooks/{id}: + get: + tags: + - Webhooks + summary: Получение вебхука + parameters: + - name: object + in: query + description: Объект + required: true + schema: + type: string + example: ul_transaction_default + - name: id + in: path + description: Идентификатор вебхука + required: true + schema: + type: string + example: f7490296-1ae1-11ec-9621-0242ac130002 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponeWebhook' + examples: + example: + $ref: '#/components/examples/ResponeWebhook' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + put: + tags: + - Webhooks + summary: Редактирование вебхука + parameters: + - name: id + in: path + description: Идентификатор вебхука + required: true + schema: + type: string + example: f7490296-1ae1-11ec-9621-0242ac130002 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestPutWebhook' + examples: + example: + $ref: '#/components/examples/RequestPutWebhook' + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponeWebhook' + examples: + example: + $ref: '#/components/examples/ResponeWebhook' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + delete: + tags: + - Webhooks + summary: Удаление вебхука + parameters: + - name: object + in: query + description: Объект + required: true + schema: + type: string + example: ul_transaction_default + - name: id + in: path + description: Идентификатор вебхука + required: true + schema: + type: string + example: f7490296-1ae1-11ec-9621-0242ac130002 + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /v1/webhooks-events: + post: + tags: + - Webhooks + summary: "Метод, имитирующий создание транзакций, для проверки работоспособн\ + ости вебхука" + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PostWebhooksEvent' + responses: + "201": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /semp/v1/payouts/registries/receipts-and-payouts: + post: + tags: + - Payouts-processing + summary: Провести выплаты на заданные суммы с одновременной декларацией доходов + и формированием чеков + operationId: addReceiptAndPayoutList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ReceiptAndPayoutList' + examples: + example: + $ref: '#/components/examples/ReceiptAndPayoutListRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/receipts: + post: + tags: + - Payouts-processing + summary: Задекларировать доходы с получением чеков по ранее проведенным выплатам + operationId: addReceiptList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ReceiptList' + examples: + example: + $ref: '#/components/examples/ReceiptListRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/with-selfemployed-check-status: + post: + tags: + - Payouts-processing + summary: "Провести выплаты самозанятым, с предварительной проверкой их стату\ + са в ФНС, но без декларации доходов и формирования чеков" + operationId: addCheckSelfemployedStatusAndPayoutList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CheckSelfemployedStatusAndPayoutList' + examples: + example: + $ref: '#/components/examples/CheckSelfemployedStatusAndPayoutListRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/payouts: + post: + tags: + - Payouts-processing + summary: Провести выплаты без проверки статуса в ФНС и декларации доходов + operationId: addPayoutList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutList' + examples: + example: + $ref: '#/components/examples/PayoutListRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/{requestId}: + get: + tags: + - Payouts-processing + summary: "Получить статус обработки выплат, загруженных в систему" + operationId: getPayoutListState + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutListState' + examples: + example: + $ref: '#/components/examples/PayoutListStateResponse' + "202": + description: REGISTRY IS LOADING + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/cancel-receipts: + post: + tags: + - Payouts-processing + summary: Аннулировать чеки в ФНС + operationId: addCancelReceiptsList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CancelReceiptList' + examples: + example: + $ref: '#/components/examples/CancelReceiptRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse' + examples: + example: + $ref: ../examples/payouts-processing.yaml#/components/examples/ListResponse + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts/registries/cancel-receipts/{requestId}: + get: + tags: + - Payouts-processing + summary: Получить статус аннулирования чеков по загруженному списку + operationId: getCancelReceiptListState + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutListState' + examples: + example: + $ref: '#/components/examples/CancelReceiptStateResponse' + "202": + description: REGISTRY IS LOADING + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/payouts: + get: + tags: + - Payouts-processing + summary: "Получить список выплат, загруженных в систему" + operationId: getPayouts + parameters: + - name: createdDate + in: query + description: Дата создания выплаты + required: false + schema: + type: string + format: date + example: 2022-03-02 + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutResponse' + examples: + example: + $ref: '#/components/examples/PayoutResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/payouts/selfemployed/{vatin}: + get: + tags: + - Payouts-processing + summary: Получить список выплат по самозанятому + operationId: getPayoutSelfemployedInfo + parameters: + - name: vatin + in: path + description: ИНН самозанятого + required: true + schema: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + example: "112233445566" + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PayoutResponse' + examples: + example: + $ref: '#/components/examples/PayoutVatinResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/registries/add-selfemployed: + post: + tags: + - Selfemployed + summary: Добавить самозанятых в систему + operationId: addSelfemployedList + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SelfemployedList' + examples: + example: + $ref: '#/components/examples/SelfemployedListRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/registries/add-selfemployed/{requestId}: + get: + tags: + - Selfemployed + summary: Получить статус добавления самозанятых в систему + operationId: getSelfemployedListState + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SelfemployedListState' + examples: + example: + $ref: '#/components/examples/SelfemployedListStateResponse' + "202": + description: REGISTRY IS LOADING + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/taxpayer-statuses: + post: + tags: + - Selfemployed + summary: Запросить статус самозанятого из ФНС + operationId: getSelfemployedFtsStatus + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestTaxpayerStatusList' + examples: + example: + $ref: '#/components/examples/RequestTaxpayerStatusList' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/taxpayer-statuses/{requestId}: + get: + tags: + - Selfemployed + summary: Запросить статус самозанятого из ФНС + operationId: getTaxpayerStatus + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TaxpayerListStatus' + examples: + example: + $ref: '#/components/examples/TaxpayerListStatusResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/accruals-and-debts: + post: + tags: + - Selfemployed + summary: Запросить данные о неоплаченных налоговых начислениях и задолженностях + самозанятого + operationId: getAccrualAndDebt + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccrualList' + examples: + example: + $ref: '#/components/examples/AccrualAndDebtListStatusRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/accruals-and-debts/{requestId}: + get: + tags: + - Selfemployed + summary: Получить данные о неоплаченных налоговых начислениях и задолженностях + самозанятого + operationId: getAccrualAndDebtFronFtsStatus + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AccrualAndDebtListStatus' + examples: + example: + $ref: '#/components/examples/AccrualAndDebtListStatusResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/payment-documents: + post: + tags: + - Selfemployed + summary: "Запросить данные платежных документов на оплату налоговых начислен\ + ий, задолженности и пеней самозанятого" + operationId: getPaymentDocuments + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccrualList' + examples: + example: + $ref: '#/components/examples/AccrualAndDebtListStatusRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/payment-documents/{requestId}: + get: + tags: + - Selfemployed + summary: "Получить данные платежных документов на оплату налоговых начислени\ + й, задолженности и пеней самозанятого" + operationId: getPaymentDocumentFromFts + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить'" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentDocumentListStatus' + examples: + example: + $ref: '#/components/examples/PaymentDocumentListStatusResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed: + get: + tags: + - Selfemployed + summary: "Получение списка самозанятых, загруженных в систему" + operationId: getSelfemployed + parameters: + - name: fromDate + in: query + description: "Дата загрузки кандидата в систему, с" + required: false + schema: + type: string + format: date + example: 2022-03-02 + - name: toDate + in: query + description: "Дата загрузки кандидата в систему, по" + required: false + schema: + type: string + format: date + example: 2022-03-02 + - name: limit + in: query + description: Количество объектов на одной странице + required: false + schema: + maximum: 1000 + minimum: 1 + type: integer + example: 1000 + default: 100 + - name: offset + in: query + description: "Количество объектов в списке, которые необходимо пропустить" + required: false + schema: + minimum: 0 + type: integer + example: 0 + default: 0 + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SelfemployedResponse' + examples: + example: + $ref: '#/components/examples/SelfemployedListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/{vatin}: + get: + tags: + - Selfemployed + summary: Получение детальной информации о самозанятом + operationId: getSelfemployedInfo + parameters: + - name: vatin + in: path + description: ИНН самозанятого + required: true + schema: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + example: "112233445566" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SelfemployedInfo' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + put: + tags: + - Selfemployed + summary: Повторно привязать самозанятого к партнеру + operationId: requestSelfemployedUniqueRights + parameters: + - name: vatin + in: path + description: ИНН самозанятого + required: true + schema: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + example: "112233445566" + requestBody: + content: + aplication/json: + schema: + $ref: '#/components/schemas/RequestSelfemployedVatin' + examples: + example: + $ref: '#/components/examples/RequestSelfemployedVatin' + responses: + "201": + description: CREATED + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/selfemployed/taxpayer-account-info: + post: + tags: + - Selfemployed + summary: Запросить информацию о состоянии Лицевого счета НП НПД + operationId: getTaxpayerAccountStatus + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/TaxpayerAccountStatusRequest' + examples: + example: + $ref: '#/components/examples/TaxpayerAccountInfoRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/taxpayer-account-info/{requestId}: + get: + tags: + - Selfemployed + summary: Получить информацию о состоянии Лицевого счета НП НПД + operationId: getTaxpayerAccountStatusFromFns + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TaxpayerAccountStatusResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/income-for-period: + post: + tags: + - Selfemployed + summary: Запросить информацию по доходу НП НПД за период + operationId: getIncomeForPeriod + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/IncomeForPeriodRequest' + examples: + example: + $ref: '#/components/examples/IncomeForPeriodRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/income-for-period/{requestId}: + get: + tags: + - Selfemployed + summary: Получить информацию по доходу НП НПД за период + operationId: getIncomeForPeriodFromFns + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/IncomeForPeriodResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/income: + post: + tags: + - Selfemployed + summary: Запросить информацию по зарегистрированным доходам с разбивкой по чекам + operationId: getIncomeV2 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/IncomeV2Request' + examples: + example: + $ref: '#/components/examples/IncomeV2Request' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListResponse_1' + examples: + example: + $ref: '#/components/examples/ListResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/selfemployed/income/{requestId}: + get: + tags: + - Selfemployed + summary: Получить информацию по зарегистрированным доходам с разбивкой по чекам + operationId: getIncomeV2FromFns + parameters: + - name: requestId + in: path + description: Уникальный идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_1' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetIncomeV2Response' + examples: + example: + $ref: '#/components/examples/GetIncomeV2Response' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + security: + - bearerAuth: [] + /semp/v1/agreement-pages: + post: + tags: + - Selfemployed-Agreements + summary: Создать параметризируемую ссылку на страницу оформления соглашения + с Альфа-Банком. + operationId: createAgreementPage + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AgreementPage' + examples: + example: + $ref: '#/components/examples/AgreementPageRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AgreementPageUrl' + examples: + example: + $ref: '#/components/examples/AgreementPageResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/dictionary/activities: + get: + tags: + - Selfemployed-Dictionaries + summary: Получить справочные данные по видам деятельности + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Activities' + examples: + example: + $ref: '#/components/examples/ActivitiesResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/dictionary/regions: + get: + tags: + - Selfemployed-Dictionaries + summary: Получить справочные данные по регионам ведения деятельности + operationId: getRegions + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Regions' + examples: + example: + $ref: '#/components/examples/RegionsResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /semp/v1/dictionary/sbp-banks: + get: + tags: + - Selfemployed-Dictionaries + summary: Получить список банков-участников СБП + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/SbpBanks' + examples: + example: + $ref: '#/components/examples/SbpBanksResponse' + "400": + description: BAD REQUEST + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_2' + "401": + description: UNAUTHORIZED + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized_1' + "403": + description: FORBIDDEN + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorForbidden' + "404": + description: NOT FOUND + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound_1' + "429": + description: TOO MANY REQUESTS + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorTooManyRequests' + "500": + description: INTERNAL SERVER ERROR + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal_1' + "503": + description: SERVICE UNAVAILABLE + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorServiceUnavailable' + /jp/v1/poa/{poaNumber}/inn/{inn}/request: + post: + tags: + - Poa + summary: Создать запрос на выгрузку МЧД + operationId: createPoaRequest + parameters: + - name: poaNumber + in: path + description: Номер МЧД + required: true + schema: + $ref: '#/components/schemas/PoaNumber' + - name: inn + in: path + description: ИНН доверителя + required: true + schema: + $ref: '#/components/schemas/Vatin_1' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePoaResponse' + examples: + example: + $ref: '#/components/examples/CreatePoaResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest_3' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/poa/requests/{requestUuid}/status: + get: + tags: + - Poa + summary: Получить статус запроса выгрузки МЧД + operationId: getPoaRequestStatus + parameters: + - name: requestUuid + in: path + required: true + schema: + $ref: '#/components/schemas/requestUuid' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetPoaRequestStatusResponse' + examples: + example: + $ref: '#/components/examples/GetPoaRequestStatusResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/RequestPoaNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/poa/requests/{requestUuid}/download: + get: + tags: + - Poa + summary: "Выгрузить МЧД (ZIP, PDF)" + operationId: getPoa + parameters: + - name: requestUuid + in: path + required: true + schema: + $ref: '#/components/schemas/requestUuid' + - name: format + in: query + description: | + Формат выгрузки МЧД: + * `ZIP` - ZIP-архив; + * `PDF` - PDF-файл. + required: true + responses: + "200": + description: OK + content: + application/pdf: + schema: + type: string + format: binary + application/zip: + schema: + type: string + format: binary + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/RequestDownloadError' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/poa/{poaNumber}/status: + get: + tags: + - Poa + summary: Запросить статус МЧД + operationId: getPoaStatus + parameters: + - name: poaNumber + in: path + description: Номер МЧД + required: true + schema: + $ref: '#/components/schemas/PoaNumber' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetPoaStatusResponse' + examples: + example: + $ref: '#/components/examples/GetPoaStatusResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/PoaNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/nominal-accounts: + get: + tags: + - Beneficiaries + summary: Получить список номинальных счетов клиента + description: Метод позволяет получить список номинальных счетов клиента + operationId: getAccounts + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccounts' + examples: + example: + $ref: '#/components/examples/GetAccounts' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/requests/{requestId}: + get: + tags: + - Beneficiaries + summary: Получить статус запроса + description: Метод позволяет получить статус запроса по `requestId` + operationId: getRequestStatus + parameters: + - name: requestId + in: path + description: Идентификатор запроса + required: true + schema: + $ref: '#/components/schemas/UUID_2' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RequestResponse' + examples: + example1: + $ref: '#/components/examples/StatusPENDINGResponse' + example2: + $ref: '#/components/examples/StatusFAILEDResponse' + example3: + $ref: '#/components/examples/StatusCOMPLETEResponse' + example4: + $ref: '#/components/examples/StatusResultDataResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries: + get: + tags: + - Beneficiaries + summary: Получить список бенефициаров номинального счета + description: Метод позволяет получить список бенефициаров номинального счета + operationId: getBeneficiaryList + parameters: + - name: accountNumber + in: query + description: Номер номинального счета + required: true + schema: + $ref: '#/components/schemas/AccountNumber' + - name: type + in: query + description: | + Тип бенефициара: + * `FL_RESIDENT` - Физ. лицо, резидент; + * `UL_RESIDENT` - Юр. лицо, резидент. + required: true + schema: + $ref: '#/components/schemas/BeneficiaryType' + - name: firstName + in: query + description: Имя + required: false + schema: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + example: Иван + - name: middleName + in: query + description: Отчество + required: false + schema: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + example: Иванoвич + - name: lastName + in: query + description: Фамилия + required: false + schema: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + example: Иванов + - name: inn + in: query + description: ИНН + required: false + schema: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + example: "112233445566" + - name: kpp + in: query + description: КПП + required: false + schema: + pattern: "^(\\d{9})$" + type: string + example: "123456789" + - name: name + in: query + description: Наименование организации + required: false + schema: + type: string + example: Акционерное общество «Ромашка» + - name: ogrn + in: query + description: Основной государственный регистрационный номер + required: false + schema: + pattern: "^(\\d{13})$" + type: string + example: "1122334455667" + - name: isVpr + in: query + description: | + Признак ВПР: + * `true` - является выгодоприобретателем; + * `false` - не является выгодоприобретателем. + required: false + schema: + type: boolean + - name: isBeneficiary + in: query + description: | + Признак бенефициара: + * `true` - является бенефициаром; + * `false` - является универсальным реципиентом. + required: false + schema: + type: boolean + - name: isActive + in: query + description: | + Признак активности бенефициара: + * `true` - активен; + * `false` - деактивирован. + required: false + schema: + type: boolean + - name: date + in: query + description: Дата выборки + required: false + schema: + $ref: '#/components/schemas/Date' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BeneficiaryListResponse' + examples: + example: + $ref: '#/components/examples/BeneficiaryListResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - Beneficiaries + summary: Создать запрос на регистрацию бенефициара + description: |- + Метод позволяет зарегистрировать бенефициара в системе. В ответ метод возвращает идентификатор запроса (requestId), который при достижении статуса `COMPLETE` будет присвоен зарегистрированному бенефициару в качестве идентификатора `beneficiaryId` + + _Примечание_: В зависимости от типа бенефициара необходимо по-разному заполнять данные. Примеры необходимых данных по каждому из типов внизу. + operationId: addBeneficiaryRequest + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/BeneficiaryRequest' + examples: + example1: + $ref: '#/components/examples/AddFLRequest' + example2: + $ref: '#/components/examples/AddULRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RequestResponse' + examples: + example: + $ref: '#/components/examples/RequestResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/{beneficiaryId}: + get: + tags: + - Beneficiaries + summary: Получить информацию о бенефициаре + description: Метод позволяет получить информацию о бенефициаре по `beneficiaryId`. + operationId: getBeneficiary + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BeneficiaryResponse' + examples: + example1: + $ref: '#/components/examples/GetFLResponse' + example2: + $ref: '#/components/examples/GetULResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + put: + tags: + - Beneficiaries + summary: Создать запрос на изменение бенефициара + description: Метод позволяет изменить информацию о бенефициаре по `beneficiaryId`. + operationId: changeBeneficiaryRequest + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ChangeBeneficiaryRequest' + examples: + example1: + $ref: '#/components/examples/ChangeFLRequest' + example2: + $ref: '#/components/examples/ChangeULRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RequestResponse' + examples: + example: + $ref: '#/components/examples/RequestResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/{beneficiaryId}/scoring: + post: + tags: + - Beneficiaries + summary: Создать запрос на проверку бенефициара + description: Метод позволяет запустить актуализацию проверки скоринга бенефициара + по `beneficiaryId`. + operationId: beneficiaryScoringRequest + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RequestResponse' + examples: + example: + $ref: '#/components/examples/RequestResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/{beneficiaryId}/requisites: + post: + tags: + - Beneficiaries + summary: Добавить платежные реквизиты бенефициара + description: |- + Метод позволяет добавить платежные реквизиты бенефициара по `beneficiaryId`. + + _Примечание_: Первые добавленные реквизиты автоматически назначаются основными для бенефициара. + operationId: addBeneficiaryRequisites + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequisiteRequest' + examples: + example1: + $ref: '#/components/examples/RequisiteAccountRequest' + example2: + $ref: '#/components/examples/RequisitePhoneRequest' + example3: + $ref: '#/components/examples/RequisitePanRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/RequisiteResponse' + examples: + example1: + $ref: '#/components/examples/RequisiteAccountResponse' + example2: + $ref: '#/components/examples/RequisitePhoneResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}: + put: + tags: + - Beneficiaries + summary: Изменить признаки платежных реквизитов бенефициара + description: |- + Метод позволяет изменить признаки платежных реквизитов бенефициара по `beneficiaryId` и `requisiteId`. + + _Примечание_: Хотя бы один активный реквизит бенефициара должен быть основным. + operationId: changeBeneficiaryRequisites + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + - name: requisiteId + in: path + description: Идентификатор реквизита + required: true + schema: + $ref: '#/components/schemas/UUID_2' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequisiteSignRequest' + examples: + example1: + $ref: '#/components/examples/IsActiveRequest' + example2: + $ref: '#/components/examples/IsMainRequest' + responses: + "200": + description: OK + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/beneficiaries/{beneficiaryId}/balance: + get: + tags: + - Beneficiaries + summary: Получить баланс бенефициара + description: Метод позволяет получить баланс бенефициара по `beneficiaryId`. + operationId: getBeneficiaryBalance + parameters: + - name: beneficiaryId + in: path + description: Идентификатор бенефициара + required: true + schema: + $ref: '#/components/schemas/UUID_2' + - name: accountNumber + in: query + description: Номер номинального счета + required: true + schema: + $ref: '#/components/schemas/AccountNumber' + - name: date + in: query + description: Дата + required: true + schema: + $ref: '#/components/schemas/Date' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BalanceResponse' + examples: + example: + $ref: '#/components/examples/BalanceResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/accounts: + summary: Метод предназначен для получения всех счетов клиента Банка + description: Счета клиента + get: + tags: + - Accounts + summary: Получение списка счетов клиента + operationId: getAccounts + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Accounts_1' + examples: + accountGet: + $ref: '#/components/examples/successAccountsGet' + accountGetEmpty: + summary: Нет Счетов + value: + accounts: [] + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/accounts/{accountNumber}: + summary: "Метод предназначен для получения информации о банковском счёте, пере\ + данном в path-параметре" + description: Информация по счёту + get: + tags: + - Accounts + summary: Получение информации по счёту + operationId: getAccountByNumber + parameters: + - name: accountNumber + in: path + description: Номер счета + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Account_2' + examples: + accountGet: + $ref: '#/components/examples/successAccountByNumber' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/accounts/{accountNumber}/requisites: + summary: "Метод предназначен для получения банковских реквизитов счёта, переда\ + нного в запросе" + description: Реквизиты счёта + get: + tags: + - Accounts + summary: Получение реквизитов счёта + operationId: getAccountRequisites + parameters: + - name: accountNumber + in: path + description: Номер счета + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AccountRequisites' + examples: + accountRequsitesRurGet: + $ref: '#/components/examples/accountRequisitesRurGet' + accountRequsitesForeignGet: + $ref: '#/components/examples/accountRequisitesForeignGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/cards: + summary: Метод предназначен для получения всех карт клиента Банка + description: Карты клиента + get: + tags: + - Cards + summary: Получение списка карт клиента + operationId: getCards + parameters: + - name: cardFilter + in: query + description: Фильтр карт + required: false + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Cards' + examples: + successCardsGet: + $ref: '#/components/examples/successCardsGet' + cardsGetEmpty: + summary: Нет карт + value: + cards: [] + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/cards/{cardId}/actions: + description: Операции и действия доступные по определенной карте + get: + tags: + - Cards + summary: Получение списка доступных действий по карте + operationId: getCardActions + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CardActions' + examples: + getCardAvailableActionsSuccessResponse: + $ref: '#/components/examples/GetCardActionsSuccessResponse' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + put: + tags: + - Cards + summary: Подтверждение действия по карте + operationId: confirmCardAction + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CardActionConfirmBody' + required: true + responses: + "200": + description: OK + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - Cards + summary: Выполнение действия по карте + operationId: createCardAction + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CardActionCreateBody' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CardActionCreateResponse' + examples: + cardBlockActionCreateSuccessResponse: + $ref: '#/components/examples/CardActionCreateSuccessResponse' + /pp/v1/cards/{cardId}/tariffs: + summary: Метод предназначен для получения информации о стоимости обслуживания + и снятия наличных + description: Тариф по дебетовой карте + get: + tags: + - Cards + summary: Получение тарифов по карте + operationId: getTariffs + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Tariffs' + examples: + tariffsGet: + $ref: '#/components/examples/successTariffsGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/cards/{cardId}/subscriptions: + summary: Метод предназначен для получения информации о подключенных уведомлениях + по операциям + description: Уведомления по операциям + get: + tags: + - Cards + summary: Получение информации о подключенных уведомлениях по карте + operationId: getSubscriptions + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Subscriptions' + examples: + successSubscriptionsGet: + $ref: '#/components/examples/successSubscriptionsGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/operations: + summary: Ресурс для работы с историей операций + description: История операций + get: + tags: + - OperationsHistory & Statements + summary: Получение истории операций + operationId: getOperationsHistory + parameters: + - name: dateFrom + in: query + description: Дата начала запроса истории операций (включительно) + required: false + schema: + type: string + format: date + - name: dateTo + in: query + description: Дата окончания запроса истории операций (включительно) + required: false + schema: + type: string + format: date + - name: accounts + in: query + description: Массив номеров счетов для выборки истории операций + required: false + schema: + type: array + items: + type: string + description: Номер счёта + - name: cards + in: query + description: Массив идентификаторов пластиковых карт для выборки истории операций + required: false + schema: + type: array + items: + type: string + description: Идентификатор пластиковой карты + - name: operationDirection + in: query + description: "Направление движения денежных средств: INCOME - приход/попол\ + нение, EXPENSE - расход/списание" + required: false + schema: + type: string + enum: + - EXPENSE + - INCOME + - name: offset + in: query + description: Параметр пагинации - Смещение от начала + required: false + schema: + type: integer + - name: limit + in: query + description: Параметр пагинации - Запрашиваемое кол-во элементов на странице + required: false + schema: + type: integer + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/OperationsHistory' + examples: + example: + $ref: '#/components/examples/successOperationsHistoryGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/operations/{id}: + summary: Ресурс для работы с одной операцией + description: Информация об операции + get: + tags: + - OperationsHistory & Statements + summary: Получение детальной информации по операции + operationId: getOperationDetails + parameters: + - name: id + in: path + description: Идентификатор операции + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/OperationDetails' + examples: + example: + $ref: '#/components/examples/successOperationDetailsGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/account: + summary: Метод предназначен для заказа выписки по счету + description: Выписка по счету + post: + tags: + - OperationsHistory & Statements + summary: Заказ выписки по счету + operationId: createAccountStatementReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountReportRequest' + required: true + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/successCreateAccountReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/credit/statement: + summary: Метод предназначен для заказа выписки по кредиту + description: Выписка по кредиту + post: + tags: + - OperationsHistory & Statements + summary: Заказ выписки по кредиту + operationId: createCreditProductReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreditProductReportRequest' + required: true + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/createCreditProductReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/account/balance/eng: + summary: Метод предназначен для заказа справки о доступном остатке на английском + description: Справка о доступном остатке на английском + post: + tags: + - Reports + summary: Заказ справки о доступном остатке на английском + operationId: createAccountBalanceEngReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountBalanceEngReportRequest' + required: true + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/successCreateAccountBalanceEngReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/account/balance/rus: + summary: Метод предназначен для заказа справки о доступном остатке на русском + description: Справка о доступном остатке на русском + post: + tags: + - Reports + summary: Заказ справки о доступном остатке на русском + operationId: createAccountBalanceRurReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountBalanceRurReportRequest' + required: true + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/successCreateAccountBalanceRurReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/credit/closed: + summary: Метод предназначен для заказа справки о закрытых кредитах + description: Справка о закрытых кредитах + post: + tags: + - Reports + summary: Заказ справки о закрытых кредитах + operationId: createClosedCreditsReport + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/createClosedCreditsReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/credit/info: + summary: Метод предназначен для заказа справки о наличии или отсутствии кредитов + description: Справка о наличии или отсутствии кредитов + post: + tags: + - Reports + summary: Заказ справки о наличии или отсутствии кредитов + operationId: createCreditInfoReport + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/createCreditInfoReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/reports/type/deposit: + summary: Метод предназначен для заказа справки по депозиту + description: Справка по депозиту + post: + tags: + - Reports + summary: Заказ справки по депозиту + operationId: createDepositReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/DepositReportRequest' + required: true + responses: + "201": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Report' + examples: + successReport: + $ref: '#/components/examples/successCreateDepositReport' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/limits/general: + summary: Метод предназначен для получения основных лимитов клиента Банка + description: Получение лимитов + get: + tags: + - Limits + summary: Получение базовых лимитов клиента + operationId: getGeneralLimits + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Limits' + examples: + example: + $ref: '#/components/examples/successLimits' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/cards/{cardId}/user-limits: + summary: "Методы предназначены для получения лимитов, установленных клиентом Б\ + анка, их добавления и удаления" + description: Получение лимитов + get: + tags: + - Limits + summary: Получение пользовательских лимитов клиента + operationId: getUserLimits + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UserLimitsGetResponse' + examples: + example: + $ref: '#/components/examples/successGetUserLimits' + post: + tags: + - Limits + summary: Создание пользовательского лимита + operationId: createUserLimit + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserLimitSeed' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/UserLimitId' + examples: + example: + $ref: '#/components/examples/successCreateUserLimit' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/cards/{cardId}/user-limits/{limitId}: + summary: "Методы предназначены для удаления лимитов, установленных клиентом Ба\ + нка" + description: Удаление лимитов установленных пользователем + delete: + tags: + - Limits + summary: Удаление пользовательского лимита + operationId: deleteUserLimit + parameters: + - name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + - name: limitId + in: path + description: Идентификатор пользовательского лимита + required: true + schema: + type: integer + responses: + "200": + description: OK + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/bonus-accounts: + summary: Ресурс для работы с бонусными счетами клиента + description: Бонусные счета клиента + get: + tags: + - Loyalty + summary: Получение списка бонусных счетов + operationId: getLoyaltyAccounts + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/LoyaltyAccount' + examples: + example: + $ref: '#/components/examples/successLoyaltyAccountsGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/bonus-account-transactions: + summary: Ресурс для работы с историей начислений лояльности + description: История начисления лояльности по транзакциям + post: + tags: + - Loyalty + summary: Получение истории начисления баллов лояльности + operationId: getLoyaltyTransactions + requestBody: + description: Запрос для фильтрации + content: + application/json: + schema: + $ref: '#/components/schemas/LoyaltyFilter' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/LoyaltyTransaction' + examples: + example: + $ref: '#/components/examples/successLoyaltyTransactionsGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/bonus-accounts/{accountNumber}: + summary: Ресурс для получения информации о начислениях по бонусному счету + description: Начисление кешбэка по бонусному счету клиента + get: + tags: + - Loyalty + summary: Получение информации о начислениях по бонусному счету + operationId: getAccountCashback + parameters: + - name: accountNumber + in: path + description: Номер счета + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AccountCashback' + examples: + example: + $ref: '#/components/examples/successAccountCashbackGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms: + summary: Метод предназначен для отправки необходимой информации в Банк для оформления + заявки на дебетовую карту + description: Формирование заявки для заказа карты + post: + tags: + - DebitCards + summary: Формирование заявки для заказа карты + operationId: createForm + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFormRequest' + examples: + example: + $ref: '#/components/examples/CreateFormRequest' + required: true + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFormResponse' + examples: + createForm: + $ref: '#/components/examples/CreateFormResponse' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/verification-passport: + summary: Метод предназначен для отправки паспортных данных пользователя с целью + его однозначной идентификации + description: Уточнение паспортных данных + post: + tags: + - DebitCards + summary: Уточнение паспортных данных + operationId: verifyPassport + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VerifyPassportRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/VerifyPassportResponse' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/verification-sms: + summary: Метод предназначен для отправки SMS кода с целью верификации определённого + действия по процессу оформления заявки на дебетовую карту + description: Отправка SMS-кода + post: + tags: + - DebitCards + summary: Отправка SMS-кода + operationId: verifySms + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + - name: phase + in: query + description: Этап процесса оформления заявки + required: true + schema: + $ref: '#/components/schemas/PhaseId' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VerifySmsRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/verifySms_200_response' + examples: + verifySmsFormCreation: + $ref: '#/components/examples/VerifySmsFormCreation' + verifySmsFormCompletion: + $ref: '#/components/examples/VerifySmsFormCompletion' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "426": + description: Данные по заявке устарели + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + UpgradeRequired: + $ref: '#/components/examples/UpgradeRequired' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/resending-sms: + summary: Метод предназначен для повторной отправки SMS кода пользователю + description: Повторная отправка SMS-кода пользователю + post: + tags: + - DebitCards + summary: Повторная отправка SMS-кода пользователю + operationId: resendSms + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + - name: phase + in: query + description: Этап процесса оформления заявки + required: true + schema: + $ref: '#/components/schemas/PhaseId' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/resendSms_200_response' + examples: + resendSms: + $ref: '#/components/examples/ResendSms' + ResendSmsStep2: + $ref: '#/components/examples/ResendSmsStep2' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Превышено количество обращений в единицу времени к сервису + dt-product-api + content: + application/json: + schema: + $ref: '#/components/schemas/TooManyRequests' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/draft: + summary: "Метод предназначен для проверки заявки по formId, является ли она че\ + рновиком" + description: Проверка наличия у заявки состояния "Черновик" + get: + tags: + - DebitCards + summary: Проверка наличия у заявки состояния "Черновик" + operationId: checkDraft + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CheckDraftResponse' + examples: + checkDraft: + $ref: '#/components/examples/CheckDraftSuccess' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Заявка не находится в статусе 'Черновик' + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + ConflictingRequest: + $ref: '#/components/examples/ConflictingRequest' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/delivery-type: + summary: "Метод предназначен для получения способов доставки пластика по задан\ + ному адресу, координатам, КЛАДР (Классификатор адресов РФ), радиусу, идентиф\ + икатору заявки" + description: Получение способов доставки + get: + tags: + - DebitCards + summary: Получение способов доставки + operationId: deliveryTypes + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + - name: accuracy + in: query + description: Точность определения координат + required: true + schema: + type: integer + example: 5 + - name: address + in: query + description: "Адрес, в радиусе которого ведется поиск" + required: true + schema: + type: string + example: "г. Москва, ул. Анохина, д. 9" + - name: kladrId + in: query + description: КЛАДР города доставки + required: true + schema: + type: string + example: "7700000000000" + - name: latitude + in: query + description: Широта + required: true + schema: + type: number + example: 55.659348 + - name: longitude + in: query + description: Долгота + required: true + schema: + type: number + example: 37.472997 + - name: radius + in: query + description: "Радиус поиска относительно указанных координат, м." + required: false + schema: + type: number + example: 3000 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DeliveryTypesResponse' + examples: + deliveryTypes: + $ref: '#/components/examples/DeliveryTypesSuccess' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/time-slots: + summary: Методы предназначены для получение списка свободных тайм-слотов и бронирования + тайм-слота для курьерской доставки по идентификатору заявки formId + description: Получение списка тайм-слотов для курьерской доставки + get: + tags: + - DebitCards + summary: Получение списка тайм-слотов для курьерской доставки + operationId: timeSlots + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + - name: isUnnamed + in: query + description: Признак неименной/именной карты + required: true + schema: + type: boolean + example: true + - name: cityId + in: query + description: Код города доставки + required: true + schema: + type: string + example: "21" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TimeSlotsResponse' + examples: + timeSlots: + $ref: '#/components/examples/TimeSlotsSuccess' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Заявка не находится в статусе 'Черновик' + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + ConflictingRequest: + $ref: '#/components/examples/ConflictingRequest' + "426": + description: Данные по заявке устарели + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + UpgradeRequired: + $ref: '#/components/examples/UpgradeRequired' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - DebitCards + summary: Бронирование тайм-слота для курьерской доставки + operationId: bookTimeSlot + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/BookTimeSlotRequest' + required: true + responses: + "200": + description: OK + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/v1/debit-cards/forms/{formId}/confirmation: + summary: Метод предназначен для завершения оформления заявки на выпуск дебетовой + карты + description: Завершение формирования заявки + post: + tags: + - DebitCards + summary: Завершение формирования заявки + operationId: formConfirmation + parameters: + - name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/FormConfirmationRequest' + examples: + example: + $ref: '#/components/examples/FormConfirmationRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/FormConfirmationResponse' + examples: + formConfirmationSuccess: + $ref: '#/components/examples/FormConfirmationSuccess' + formConfirmationNeedSms: + $ref: '#/components/examples/FormConfirmationNeedSms' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceError' + examples: + InvalidRequest: + $ref: '#/components/examples/InvalidRequest' + FormNotFound: + $ref: '#/components/examples/FormNotFound' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /pp/open-banking/v1.3/accounts: + get: + tags: + - Accounts + summary: Получение списка счетов + operationId: getAccounts + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountsResponse' + examples: + example: + $ref: '#/components/examples/GetAccountsResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/accounts/{accountId}: + get: + tags: + - Accounts + summary: Получение детальной информации о счете по его идентификатору + operationId: getAccount + parameters: + - name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountsResponse' + examples: + example: + $ref: '#/components/examples/GetAccountResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/balances: + get: + tags: + - Balances + summary: Остаток денежных средств по всем счетам + operationId: getBalances + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BalanceResponse_1' + examples: + example: + $ref: '#/components/examples/BalancesResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/accounts/{accountId}/balances: + get: + tags: + - Balances + summary: Баланс банковского счета по идентификатору accountId + operationId: getAccountIdBalances + parameters: + - name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BalanceResponse_1' + examples: + example: + $ref: '#/components/examples/BalanceResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/transactions: + get: + tags: + - Transactions + summary: Список операций по всем счетам + operationId: getAllTransactions + parameters: + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + examples: + example: + $ref: '#/components/examples/GetTransactionsResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/accounts/{accountId}/transactions: + get: + tags: + - Transactions + summary: Ресурс операции по счету с идентификатором accountId + operationId: getAccountTransactions + parameters: + - name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + - name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + - name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TransactionResponse' + examples: + example: + $ref: '#/components/examples/GetTransactionsResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/payment-cards: + get: + tags: + - PaymentCards + summary: Получение списка платежных карт + operationId: getPaymentCards + parameters: + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AccountPaymentCardsResponse' + examples: + example: + $ref: '#/components/examples/GetCardsResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /pp/open-banking/v1.3/accounts/{accountId}/payment-cards: + get: + tags: + - PaymentCards + summary: Получение списка платежных карт по идентификатору счета + operationId: getAccountPaymentCards + parameters: + - name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + - name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляц\ + ии. Если необходимо, то Сторонний поставщик передает обратно значение ид\ + ентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в\ + \ соответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID)\ + \ URN Namespace\"." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AccountPaymentCardsResponse' + examples: + example: + $ref: '#/components/examples/GetCardResponseExample' + "400": + description: "Запрос имеет неверное, отсутствующее или несовместимое тел\ + о JSON, параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в\ + \ полезной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия + (scope) необходимый для доступа к ресурсу + url: https://example.com/error-description + "405": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + "429": + description: "Операция была отклонена, так как слишком много запросов бы\ + ло сделано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора ко\ + рреляции. Если необходимо, то Сторонний поставщик передает обратно\ + \ значение идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + /reports/payments-sbp: + post: + tags: + - SBP + summary: Инициирование формирования отчета для X5 + description: Метод инициирует асинхронный процесс формирования отчета + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ReportRequest' + responses: + "201": + description: Идентификатор зарегистрированного запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ReportResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/terminals: + post: + tags: + - SBP + summary: Добавление кассы к ТСП в СБП + description: Метод позволяет зарегистрировать терминал ТСП в СБП + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegTerminalRequest' + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/RegTerminalResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/merchants/{merchantId}: + get: + tags: + - SBP + summary: Получение информации о ТСП и терминалах в СБП + description: Метод позволяет получить информацию о ТСП и подключенных терминалах + СБП + parameters: + - name: merchantId + in: path + description: Идентификатор ТСП + required: true + schema: + pattern: "^.{12}$" + type: string + example: MA0000002752 + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/MerchantInfoResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/legal: + get: + tags: + - SBP + summary: Получение информации о ЮЛ в СБП + description: Метод позволяет получить информацию о ЮЛ и списка ТСП в СБП + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/LegalInfoResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls/one-time-use: + post: + tags: + - SBP + summary: Зарегистрировать новую платежную одноразовую ссылку + description: Метод создает новую платежную одноразовую ссылку + operationId: registerOneTimeUseUrl + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OneTimePaymentUrlRequest' + examples: + example: + $ref: '#/components/examples/paymentUrlsOneTimeUseRequest' + responses: + "201": + description: Информация о зарегистрированной платежной ссылке + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentUrl' + examples: + example: + $ref: '#/components/examples/paymentUrlsOneTimeUseResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls/reusable: + post: + tags: + - SBP + summary: Зарегистрировать новую платежную многоразовую ссылку + description: Метод создает новую платежную многоразовую ссылку + operationId: registerReusableUrl + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ReusablePaymentUrlRequest' + examples: + example: + $ref: '#/components/examples/paymentUrlsReusableRequest' + responses: + "201": + description: Информация о зарегистрированной платежной ссылке + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentUrl' + examples: + example: + $ref: '#/components/examples/paymentUrlsReusableResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls/batch: + post: + tags: + - SBP + summary: Зарегистрировать новые платёжные ссылки + description: Метод позволяет зарегистрировать массив новых платёжных ссылок + operationId: registerPaymentUrls + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PostBatchPaymentUrlRequest' + examples: + example: + $ref: '#/components/examples/registerPaymentUrlsRequest' + responses: + "201": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/PostBatchPaymentUrlResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls: + get: + tags: + - SBP + summary: Получить зарегистрированные платежные ссылки клиента + description: "Метод возвращает платежные ссылки, зарегистрированные клиентом" + operationId: getPaymentUrlsByClientId + parameters: + - name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + - name: qrcId + in: query + description: Идентификатор платежной ссылки + required: false + schema: + maxLength: 32 + minLength: 1 + type: string + example: AO1000670LSS7DN18SJQDNP4B05KLJL2 + - name: onlyActive + in: query + description: Вернуть только действующие ссылки (Да/Нет). Действующими считаются + неоплаченные и с неистекшим сроком действия (expirationDate в будущем). + Значение по умолчанию false. + required: false + schema: + type: boolean + example: false + - name: sort + in: query + description: "Сортировка результатов поиска (не более трех параметров). Ес\ + ли параметры сортировки не заданы, записи сортируются по убыванию registrationDate.\ + \ Возможные значения: name, merchantId, payeeAccount, amount, qrcType, takeTax,\ + \ registrationDate, expirationDate." + required: false + schema: + type: array + items: + type: string + example: "?sort=amount,asc&sort=qrcType,asc&sort=registrationDate,desc" + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + responses: + "200": + description: "Список платежных ссылок, зарегистрированных пользователем" + content: + application/json: + schema: + $ref: '#/components/schemas/GetPaymentUrlsResponse' + examples: + example: + $ref: '#/components/examples/getPaymentUrls' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + patch: + tags: + - SBP + summary: Обновить статусы платёжных ссылок + description: Метод позволяет обновлять статусы платёжных ссылок + operationId: updateStatusPaymentUrls + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStatusPaymentUrls' + examples: + example: + $ref: '#/components/examples/updateStatusPaymentUrlsRequest' + responses: + "204": + description: No Content + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls/batch/{batchId}: + get: + tags: + - SBP + summary: Получить результат регистрации массива платёжных ссылок + description: Метод возвращает результат регистрации массива платёжных ссылок + operationId: getPaymentUrlsByBatchId + parameters: + - name: batchId + in: path + description: Идентификатор массива платёжных ссылок + required: true + schema: + type: string + format: uuid + example: a7631fbb-f94f-4c17-1e13-0e96a3a77113 + - name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/GetBatchPaymentUrlResponse' + examples: + example: + $ref: '#/components/examples/getPaymentUrlsResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/payment-urls/{qrcId}/data: + get: + tags: + - SBP + summary: Получить данные по зарегистрированной платёжной ссылке клиента (ЮЛ) + description: "Метод возвращает платёжные данные по ссылке, зарегистрированно\ + й клиентом" + operationId: getPaymentDataByQRc + parameters: + - name: qrcId + in: path + description: Идентификатор платежной ссылки + required: true + schema: + type: string + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + responses: + "200": + description: "Данные по платежный ссылке, зарегистрированной пользовател\ + ем" + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentUrlData' + examples: + example: + $ref: '#/components/examples/getPaymentDataByQRc' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/incoming-payments: + get: + tags: + - SBP + summary: Получить список входящих платежей + description: Метод запрашивает информацию о входящих платежах клиента + operationId: getIncomingPayments + parameters: + - name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + - name: qrcId + in: query + description: Идентификатор платежной ссылки + required: false + schema: + maxLength: 32 + minLength: 1 + type: string + example: AO1000670LSS7DN18SJQDNP4B05KLJL2 + - name: sort + in: query + description: "Сортировка результатов поиска (не более трех параметров). Во\ + зможные значения: qrcId, amount, taxAmount, paymentPurpose, payeeAccount,\ + \ timestamp." + required: false + schema: + type: array + items: + type: string + example: "?sort=amount,asc&sort=timestamp,desc" + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + responses: + "200": + description: "Информация о платежах, совершенных по платежным ссылкам" + content: + application/json: + schema: + $ref: '#/components/schemas/GetIncomingPaymentsResponse' + examples: + example: + $ref: '#/components/examples/getIncomingPayments' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/outgoing-payments: + get: + tags: + - SBP + summary: Получить список исходящих платежей клиента + description: Метод запрашивает информацию о исходящих платежах клиента + operationId: getOutgoingPayments + parameters: + - name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + - name: outgoingPaymentId + in: query + description: Идентификатор исходящего платежа + required: false + schema: + type: string + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + - name: qrcId + in: query + description: Идентификатор платежной ссылки + required: false + schema: + maxLength: 32 + minLength: 1 + type: string + example: AO1000670LSS7DN18SJQDNP4B05KLJL2 + - name: sort + in: query + description: "Сортировка результатов поиска (не более трех параметров). Ес\ + ли параметры сортировки не заданы, записи сортируются по убыванию outgoingPaymentId.\ + \ Возможные значения: status, amount, payerAccount, paymentPurpose, timestamp,\ + \ outgoingPaymentId." + required: false + schema: + type: array + items: + type: string + example: "?sort=status,asc&sort=timestamp,desc" + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/GetOutgoingPaymentsResponse' + examples: + example: + $ref: '#/components/examples/getOutgoingPaymentsResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/outgoing-payments/one-pay: + post: + tags: + - SBP + summary: Выполнить исходящий платеж за один шаг + description: Метод инициирует проведение проверок и выполнение платежа + operationId: executeOneStepOutgoingPayment + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OneStepExecuteOutgoingPayment' + examples: + example: + $ref: '#/components/examples/executeOneStepOutgoingPaymentRequest' + responses: + "201": + description: Успешная инициация платежа + content: + application/json: + schema: + $ref: '#/components/schemas/OneStepExecuteOutgoingPaymentResponse' + examples: + example: + $ref: '#/components/examples/executeOneStepOutgoingPaymentResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/outgoing-payments/{outgoingPaymentId}/status: + get: + tags: + - SBP + summary: Получить статус исходящего платежа + description: Метод запрашивает информацию о статусе исходящего платежа по идентификатору + operationId: getOutgoingPaymentStatus + parameters: + - name: outgoingPaymentId + in: path + description: Идентификатор исходящего платежа + required: true + schema: + type: string + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + - name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + responses: + "200": + description: Успешный результат + content: + application/json: + schema: + $ref: '#/components/schemas/OutgoingPaymentStatus' + examples: + example: + $ref: '#/components/examples/outgoingPaymentStatusResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Слишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /1c/merchants/{merchantId}: + get: + tags: + - B2B SPB 1C + summary: Проверка настроек и аутентификации мерчанта + description: "[ВХОДЯЩИЙ] " + parameters: + - name: merchantId + in: path + required: true + schema: + type: string + example: MF0000000001 + - name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + responses: + "200": + description: Информация о мерчанте + content: + application/json: + schema: + $ref: '#/components/schemas/inline_response_200' + examples: + example: + $ref: '#/components/examples/merchantResponse' + "400": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadRequest' + "401": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadCredentials' + "403": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/authorizationException' + "404": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/notFoundException' + "429": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/tooManyRequestsException' + "500": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/internalServerErrorException' + "503": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/timeoutException' + /1c/payments/search: + post: + tags: + - B2B SPB 1C + summary: Получение информации об оплате + description: "[ВХОДЯЩИЙ] " + parameters: + - name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/payments_search_body' + examples: + example: + $ref: '#/components/examples/PaymentsSearchBody' + required: true + responses: + "200": + description: Коллекция результатов оплаты + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentInfoArray' + examples: + example: + $ref: '#/components/examples/paymentInfo' + "400": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadRequest' + "401": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadCredentials' + "403": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/authorizationException' + "404": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/notFoundException' + "429": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/tooManyRequestsException' + "500": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/internalServerErrorException' + "503": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/timeoutException' + /1c/payment-link/{qrId}: + get: + tags: + - B2B SPB 1C + summary: Получение данных по функциональной ссылке + description: "[ВХОДЯЩИЙ] " + parameters: + - name: qrId + in: path + required: true + schema: + type: string + example: EX2E009997EAL2DG8VFAEN07M1VH92DW + - name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + responses: + "200": + description: Информация по ссылке + content: + application/json: + schema: + $ref: '#/components/schemas/LinkDetail' + "400": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadRequest' + "401": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadCredentials' + "403": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/authorizationException' + "404": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/notFoundException' + "429": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/tooManyRequestsException' + "500": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/internalServerErrorException' + "503": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/timeoutException' + /1c/payment-link/reusable: + post: + tags: + - B2B SPB 1C + summary: Регистрация многоразовой платёжной ссылки + description: "[ВХОДЯЩИЙ] " + parameters: + - name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ReusableLinkRequest' + examples: + example: + $ref: '#/components/examples/ReusableLinkBody' + required: true + responses: + "200": + description: Успешная регистрация + content: + application/json: + schema: + $ref: '#/components/schemas/LinkResponse' + "400": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadRequest' + "401": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadCredentials' + "403": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/authorizationException' + "404": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/notFoundException' + "429": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/tooManyRequestsException' + "500": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/internalServerErrorException' + "503": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/timeoutException' + /1c/payment-link/one-time-use: + post: + tags: + - B2B SPB 1C + summary: Регистрация одноразовой платёжной ссылки + description: "[ВХОДЯЩИЙ] " + parameters: + - name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OneTimeLinkRequest' + examples: + example: + $ref: '#/components/examples/oneTimeLinkBody' + required: true + responses: + "200": + description: Успешная регистрация + content: + application/json: + schema: + $ref: '#/components/schemas/LinkResponse' + "400": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadRequest' + "401": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/errorBadCredentials' + "403": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/authorizationException' + "404": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/notFoundException' + "429": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/tooManyRequestsException' + "500": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/internalServerErrorException' + "503": + description: Ошибка + content: + application/json: + schema: + $ref: '#/components/schemas/BusinessException' + examples: + example: + $ref: '#/components/examples/timeoutException' + /b2cpay/jp/v1/payments: + get: + tags: + - b2cpay + summary: Сформировать отчетность по платежам по номеру транзакции или за период + description: Метод получения отчетности по платежам по транзакции или по периоду + operationId: getPaymentPhoneReport + parameters: + - name: b2cClientId + in: query + description: "Идентификатор клиента, от имени которого интегратором отправ\ + ляется платеж" + schema: + type: string + - name: partnerId + in: query + description: Идентификатор партнера + required: true + schema: + type: integer + format: int64 + - name: startDate + in: query + description: Дата начала периода + schema: + type: string + format: date-time + - name: finishDate + in: query + description: Дата окончания периода + schema: + type: string + format: date-time + - name: transactionId + in: query + description: Идентификатор транзакции + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentReportResponse' + examples: + example: + $ref: '#/components/examples/getPhonePaymentReportResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + post: + tags: + - b2cpay + summary: Отправить платеж или пакет платежей физическому лицу через СБП + description: Метод отправки платежа или пакета платежей + operationId: addPhonePayment + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentRequest' + examples: + example: + $ref: '#/components/examples/addPhonePaymentRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentResponse' + examples: + example: + $ref: '#/components/examples/addPhonePaymentResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /b2cpay/jp/v1/payments/packages/{packageId}: + description: Метод получения отчетности по платежам по пакету транзакций + get: + tags: + - b2cpay + summary: Сформировать отчетность по платежам по пакету транзакций + operationId: getPaymentPackagePhoneReport + parameters: + - name: packageId + in: path + description: Идентификатор пакета платежей + required: true + schema: + type: integer + format: int64 + - name: b2cClientId + in: query + description: "Идентификатор клиента, от имени которого интегратором отправ\ + ляется платеж" + schema: + type: string + - name: partnerId + in: query + description: Идентификатор партнера + required: true + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentReportResponse' + examples: + example: + $ref: '#/components/examples/getPhonePaymentReportResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /b2cpay/jp/v1/clients/checks: + description: Метод проверки возможности выплаты на ФЛ + post: + tags: + - b2cpay + summary: Отправить запрос на проверку возможности выплаты физическому лицу через + СБП по реквизитам + operationId: addCheckPhonePayment + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentCheckRequest' + examples: + example: + $ref: '#/components/examples/addPhonePaymentCheckRequest' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentCheckResponse' + examples: + example: + $ref: '#/components/examples/addPhonePaymentCheckResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /b2cpay/jp/v1/clients/checks/{checkId}: + description: Метод получения результатов проверки возможности выплаты на ФЛ + get: + tags: + - b2cpay + summary: Получить результат проверки возможности выполнить платеж на ФЛ по реквизитам + operationId: getCheckPaymentPhoneStatus + parameters: + - name: checkId + in: path + description: Идентификатор асинхронного запроса на проверку возможности платежа + required: true + schema: + type: string + - name: b2cClientId + in: query + description: "Идентификатор клиента, от имени которого интегратором отправ\ + ляется платеж" + schema: + type: string + - name: partnerId + in: query + description: Идентификатор партнера + required: true + schema: + type: integer + format: int64 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhonePaymentCheckStatusResponse' + examples: + example: + $ref: '#/components/examples/getPhonePaymentCheckStatusResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /b2cpay/jp/v1/banks: + get: + tags: + - b2cpay + summary: Получить список банков НСПК для платежей на ФЛ по реквизитам + description: Метод получения списка банков НСПК + operationId: getBanksList + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/BanksResponse' + examples: + example: + $ref: '#/components/examples/getBanksResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /b2cpay/jp/v1/clients/info: + description: Метод получения внутреннего b2cpayClientId клиента по ИНН + get: + tags: + - b2cpay + summary: Получить ClientID по ИНН клиента + operationId: getINNByClientId + parameters: + - name: partnerId + in: query + description: Идентификатор партнера + required: true + schema: + type: integer + format: int64 + - name: inn + in: query + description: ИНН ЮЛ + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClientInnResponse' + examples: + example: + $ref: '#/components/examples/getClientInnResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /pp/v1/credit-offers: + description: Получение кредитный предложений физического лица + get: + tags: + - Credit Offers + summary: Запрос получения кредитных предложений + operationId: getCreditOffers + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreditOffers' + examples: + example: + $ref: '#/components/examples/successCreditOffersGet' + "400": + description: Authorization отсутствует в заголовках запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/qrcs: + post: + tags: + - C2B SBP + summary: Сгенерировать QR-код для оплаты + description: Метод позволяет сгенерировать QR-код для оплаты + operationId: GenerateQRCode + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GetStatisOrDynamicQRc' + examples: + example: + $ref: '#/components/examples/GetStatisOrDynamicQRc' + responses: + "201": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/GetQRcResponse' + examples: + example: + $ref: '#/components/examples/GetQRcResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/qrc-status: + get: + tags: + - C2B SBP + summary: Получить статус оплаты QR-кода и кассовой платёжной ссылки + description: Метод позволяет получить статус оплаты QR-кода и кассовой платёжной + ссылки + operationId: GetQRCodeStatus + parameters: + - name: termNo + in: query + description: Уникальный идентификатор терминала + required: true + schema: + type: string + example: 30000600 + - name: qrcId + in: query + description: Идентификатор QR-кода + required: false + schema: + pattern: "^.{32}$" + type: string + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + - name: payrrn + in: query + description: Референсный идентификатор запроса + required: false + schema: + type: string + example: "012345678912" + - name: messageId + in: header + description: Уникальный идентификатор сообщения + required: false + schema: + type: string + example: 123Rersal_Num567 + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/GetQRcStatusResponse' + examples: + example: + $ref: '#/components/examples/GetQRcStatusResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/subscriptions: + post: + tags: + - C2B SBP + summary: Сгенерировать QR-код для привязки счёта/подписки СБП + description: Метод позволяет сгенерировать QR-код для привязки счёта/подписки + СБП + operationId: GenerateQRCodeSubscription + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/GetQRcSubscriptionRequest' + examples: + example: + $ref: '#/components/examples/GetQRcSubscriptionRequest' + responses: + "201": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/GetQRcSubscriptionResponse' + examples: + example: + $ref: '#/components/examples/GetQRcSubscriptionResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/petitions: + post: + tags: + - C2B SBP + summary: Произвести оплату с привязанного счёта по инициативе ТСП + description: Метод позволяет произвести оплату с привязанного счёта по инициативе + ТСП + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentFromBindedAccountRequest' + examples: + example: + $ref: '#/components/examples/PaymentFromBindedAccountRequest' + responses: + "201": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentFromBindedAccountResponse' + examples: + example: + $ref: '#/components/examples/PaymentFromBindedAccountResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/refund: + post: + tags: + - C2B SBP + summary: Запросить возврат оплаты QR-кода и кассовой платёжной ссылки + description: Метод позволяет запросить возврат оплаты QR-кода и кассовой платёжной + ссылки + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/QRcRefundRequest' + examples: + example: + $ref: '#/components/examples/QRcRefundRequest' + responses: + "201": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/QRcRefundResponse' + examples: + example: + $ref: '#/components/examples/QRcRefundResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/refund/status: + get: + tags: + - C2B SBP + summary: Получить статус возврата СБП + description: Метод позволяет получить статус возврата СБП + parameters: + - name: termNo + in: query + description: Уникальный идентификатор терминала + required: true + schema: + type: string + example: 30000600 + - name: payrrn + in: query + description: Референсный идентификатор запроса + required: false + schema: + type: string + example: "012345678912" + - name: originalTrxId + in: query + description: Уникальный идентификатор платежа в НСПК + required: false + schema: + type: string + example: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + - name: trxId + in: query + description: Уникальный идентификатор операции возврата в НСПК + required: false + schema: + type: string + example: 1SA32XD5F6G78J9K0HC4S5C6D4V7D5J2 + - name: messageId + in: query + description: Уникальный идентификатор сообщения + required: false + schema: + type: string + example: 123Rersal_Num567 + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/GetQRcRefundStatusResponse' + examples: + example: + $ref: '#/components/examples/GetQRcRefundStatusResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/terminals/{termNo}/cash-qrcs: + post: + tags: + - C2B SBP + summary: Зарегистрировать кассовую ссылку СБП + description: Метод позволяет зарегистрировать кассовую ссылку СБП + operationId: RegisterCashQRCode + parameters: + - name: termNo + in: path + description: Уникальный идентификатор терминала + required: true + schema: + type: string + example: 30000600 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CashQRcsRegistrationRequest' + examples: + example: + $ref: '#/components/examples/CashQRcsRegistrationRequest' + responses: + "201": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/CashQRcsRegistrationResponse' + examples: + example: + $ref: '#/components/examples/CashQRcsRegistrationResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /sbp/jp/v1/terminals/{termNo}/cash-qrcs/{qrcId}/activation: + post: + tags: + - C2B SBP + summary: Активировать кассовую ссылку СБП + description: Метод позволяет активировать кассовую ссылку СБП + operationId: ActivateCashQRCode + parameters: + - name: termNo + in: path + description: Уникальный идентификатор терминала + required: true + schema: + type: string + example: 30000600 + - name: qrcId + in: path + description: Идентификатор QR-кода + required: true + schema: + pattern: "^.{32}$" + type: string + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CashQRcsActivationRequest' + examples: + example: + $ref: '#/components/examples/CashQRcsActivationRequest' + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/CashQRcsActivationResponse' + examples: + example: + $ref: '#/components/examples/CashQRcsActivationResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + delete: + tags: + - C2B SBP + summary: Деактивировать кассовую ссылку СБП + description: Метод позволяет деактивировать кассовую ссылку СБП + operationId: DeactivateCashQRCode + parameters: + - name: termNo + in: path + description: Уникальный идентификатор терминала + required: true + schema: + type: string + example: 30000600 + - name: qrcId + in: path + description: Идентификатор QR-кода + required: true + schema: + pattern: "^.{32}$" + type: string + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + responses: + "204": + description: "Успешный ответ, без тела сообщения" + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/salary-project/accounts/applications: + post: + tags: + - Salary-Project + summary: Создать электронный реестр на открытие счетов + operationId: createAccountsOpeningApplication + parameters: + - name: X-Salary-Signatures + in: header + description: Открепленные PKCS7 подписи запроса + required: false + schema: + type: string + example: "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIIGMzCCBBugAwIBAgIIQ+Ua6h49X/kwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUwHhcNMjQwNTI3MTMzNTAwWhcNMjkwNTI3MTMzNTAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYDVQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29yZVJTQSBTaWduZXIyIDIwNDggYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBhbGZhYmFuay5ydTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbaUlic4XF47DJtoFQKNnd46jvaoE9pyxByuEKQkZY8Na5XWNuyr5ZALF6RTYXRS+i2wqig+zsGhEKG5rM2VZFJB4p6VvwbULzDeH08tEw01hvnIiUFxrlVlpMIM649rLaMUTZnh8RKq23WkvDxPaEEeLV0f0sgeHpBf2nV7ZeM4w6LdC2T/hnYAy7VxIS+BN2nDGOIePqh+lGgUZIHY9cO3IbN7yWSQQSC7hQ696RC9L5vWedOXb6CmyWlFsuOnAgp+O3z2U1wbovCQ48CU8VprzjLorw/UTz/qJr7uGGICuY7M1Go7qLvICsHclkKqvRcCMLBGxdg6RBkA+6t96cCAwEAAaOCAScwggEjMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFp1la5QGzpdMD7SCyadt9CVfElrMAsGA1UdDwQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAwYIKwYBBQUHAwQwgccGA1UdHwSBvzCBvDA8oDqgOIY2aHR0cDovL2FydGFwcC9hcnRpZmFjdG9yeS9UcnVzdENvcmUvQ1JMcy90cnVzdGNvcmUuY3JsMDqgOKA2hjRodHRwOi8vaGF2ZW4ubW9zY293LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMECgPqA8hjpodHRwOi8vczAxZHBydXByYnMubW9zY293LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMA0GCSqGSIb3DQEBCwUAA4ICAQARCvm8JwBOGonGKMlnwyxnFX2aV1qIkzMgo7ILaCXT/MybvPH/3GQByBOUsASFU7cod57qEOOyQSN/JTQ/ZdKz3B8goGoO1XC/toybaTib92Dru7XyiJAeOLHksDjMQ7U6Xgk/51xoPa6AvZyOUWNW0KUdQFWlfyJeH+Gt4Xr1OH+LYuUMhiVubUPn+edW/PW8WTzlpjvd55/e69YViSJBuNenV0cmxKe/xWD7ZnfGfBsf+Sy/xhfjP0nFd7qANeQJXmb07gl7zJUyV0oK7fXyHO7Rg2wVcWEr8p9uS/sTS0ZnXJZKN3/OO+zp9UPM23uzZNuySsBbc7QNlJ3c8GLL/R93xvE3BNV+DtZVbu7xaqcWZmFEnfp0iTVCfMC3d9Cig+KZ5NKBQp+vB0A4+vj8jO/ZCCjtho3nqeJ+exO2AHgLYj6XaeCTed4fW0ENt0XWNrFaVW/wRyHOXvEN8Ocj8LV5Xtwh6xPuwSbas2VL4v7V50O7V5RA4ZucdpdmRj5z/qkqkirGRcWnf+UWwjniI+BzCGlsPjGJmGgl8OjGUnb/vZ4fN1g2QVBcS1riln0mQDPbaBJNtFOSc3GCh+HttX075tinnux348YgqsHeKfsVZ6+5gmrumdaS8uN/L/cgFtPJFfwpbz5YGq98owU8BVlodP1eM8C5eEPU1X0BGQAAMYICkTCCAo0CAQEwgcowgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUCCEPlGuoePV/5MA0GCWCGSAFlAwQCAQUAoIGYMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MTAxMDIyMzEwM1owLQYJKoZIhvcNAQk0MSAwHjANBglghkgBZQMEAgEFAKENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQgtePFfYxpG652D9kwL4qQku/nF/GmYibgbJMWYU3kMj0wDQYJKoZIhvcNAQELBQAEggEAqPJ/bBA+ft7AxpdkOmpzIrsK2X6aoxg326IMoTUkyT3xNWZux6cYJCl58XjfCKMUCQzrquruSzaP9+P8tL5nW/lcttiTXZNis3VcUOyN936Eql/jUPilsL7jIOcB6WOVDnfhjQI2/oGKjDIOKKoie9QhTBVNxPQBjmRnntRyP5JXZHRiS0dyV8nbKdJ/oFpteon58ES95DvcyDZwOIaJ5zj1GzoxzTcfRbPZlK4wXhhbxORt01CuA+VfmhuXX1jbOVIYF2StM9XdXG5X25SsYG+42D2c5noSbhh5vj5TA+1I+V9TCspv3g2ULjSDva7RnkTcY0H2XjBSy4OtR2b5pAAAAAAAAA==,MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIIHMzCCBRugAwIBAgIIYnDbwSiFECUwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUwHhcNMjQwNTI3MTMxMjAwWhcNMjkwNTI3MTMxMjAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYDVQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29yZVJTQSBTaWduZXIxIDQwOTYgYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBhbGZhYmFuay5ydTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM62+ggXZkPhAeWYqhqoFDazgSVjKOj4ZL5Alx0P1Jg6iMsA1d3ZiXBf5xGHx6xkeeyX1jlOOxK5NeFRDLXP0rmxJIKr8sgKcLxArH2LxqQ7HJHeXzmHaWRnU8jB/al+gHPVGTZmsSJWBGhxXRiwMR25LrTx7rBJ7lUDKa+Ja6y+Hbt6jdZG+dH9E004EOrIRim5aANMI9aO71eZWVZhCWMJ6mhwPv+6adUMiY16YF9ldBbQqmgtOIUELFBX + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAccountsApplicationRequest' + examples: + example: + $ref: '#/components/examples/Request' + required: true + responses: + "201": + description: Запрос принят в обработку + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAccountsApplicationResponse' + examples: + example: + $ref: '#/components/examples/Response' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/salary-project/accounts/applications/{applicationId}: + get: + tags: + - Salary-Project + summary: Получить статус электронного реестра на открытие счетов + operationId: getAccountsOpeningApplicationStatus + parameters: + - name: applicationId + in: path + required: true + schema: + maxLength: 35 + type: string + responses: + "200": + description: Успешное получение статуса + content: + application/json: + schema: + $ref: '#/components/schemas/GetAccountsApplicationResponse' + examples: + example: + $ref: '#/components/examples/Response' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/salary-project/payroll/applications: + post: + tags: + - Salary-Project + summary: Отправить зарплатную ведомость + operationId: createPayrollApplication + parameters: + - name: X-Salary-Signatures + in: header + description: Открепленные PKCS7 подписи запроса + required: false + schema: + type: string + example: "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIIGMzCCBBugAwIBAgIIQ+Ua6h49X/kwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUwHhcNMjQwNTI3MTMzNTAwWhcNMjkwNTI3MTMzNTAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYDVQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29yZVJTQSBTaWduZXIyIDIwNDggYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBhbGZhYmFuay5ydTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbaUlic4XF47DJtoFQKNnd46jvaoE9pyxByuEKQkZY8Na5XWNuyr5ZALF6RTYXRS+i2wqig+zsGhEKG5rM2VZFJB4p6VvwbULzDeH08tEw01hvnIiUFxrlVlpMIM649rLaMUTZnh8RKq23WkvDxPaEEeLV0f0sgeHpBf2nV7ZeM4w6LdC2T/hnYAy7VxIS+BN2nDGOIePqh+lGgUZIHY9cO3IbN7yWSQQSC7hQ696RC9L5vWedOXb6CmyWlFsuOnAgp+O3z2U1wbovCQ48CU8VprzjLorw/UTz/qJr7uGGICuY7M1Go7qLvICsHclkKqvRcCMLBGxdg6RBkA+6t96cCAwEAAaOCAScwggEjMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFp1la5QGzpdMD7SCyadt9CVfElrMAsGA1UdDwQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAwYIKwYBBQUHAwQwgccGA1UdHwSBvzCBvDA8oDqgOIY2aHR0cDovL2FydGFwcC9hcnRpZmFjdG9yeS9UcnVzdENvcmUvQ1JMcy90cnVzdGNvcmUuY3JsMDqgOKA2hjRodHRwOi8vaGF2ZW4ubW9zY293LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMECgPqA8hjpodHRwOi8vczAxZHBydXByYnMubW9zY293LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMA0GCSqGSIb3DQEBCwUAA4ICAQARCvm8JwBOGonGKMlnwyxnFX2aV1qIkzMgo7ILaCXT/MybvPH/3GQByBOUsASFU7cod57qEOOyQSN/JTQ/ZdKz3B8goGoO1XC/toybaTib92Dru7XyiJAeOLHksDjMQ7U6Xgk/51xoPa6AvZyOUWNW0KUdQFWlfyJeH+Gt4Xr1OH+LYuUMhiVubUPn+edW/PW8WTzlpjvd55/e69YViSJBuNenV0cmxKe/xWD7ZnfGfBsf+Sy/xhfjP0nFd7qANeQJXmb07gl7zJUyV0oK7fXyHO7Rg2wVcWEr8p9uS/sTS0ZnXJZKN3/OO+zp9UPM23uzZNuySsBbc7QNlJ3c8GLL/R93xvE3BNV+DtZVbu7xaqcWZmFEnfp0iTVCfMC3d9Cig+KZ5NKBQp+vB0A4+vj8jO/ZCCjtho3nqeJ+exO2AHgLYj6XaeCTed4fW0ENt0XWNrFaVW/wRyHOXvEN8Ocj8LV5Xtwh6xPuwSbas2VL4v7V50O7V5RA4ZucdpdmRj5z/qkqkirGRcWnf+UWwjniI+BzCGlsPjGJmGgl8OjGUnb/vZ4fN1g2QVBcS1riln0mQDPbaBJNtFOSc3GCh+HttX075tinnux348YgqsHeKfsVZ6+5gmrumdaS8uN/L/cgFtPJFfwpbz5YGq98owU8BVlodP1eM8C5eEPU1X0BGQAAMYICkTCCAo0CAQEwgcowgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUCCEPlGuoePV/5MA0GCWCGSAFlAwQCAQUAoIGYMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MTAxMDIyMzU0MFowLQYJKoZIhvcNAQk0MSAwHjANBglghkgBZQMEAgEFAKENBgkqhkiG9w0BAQsFADAvBgkqhkiG9w0BCQQxIgQgAMHlWtd4sPzSuIVyGdmb3UzPu/j71+tReEDSQP9+wmowDQYJKoZIhvcNAQELBQAEggEAmnrE5fN56ogpK5UcgipdbsGO1+Hg6B2Z8iDVnCLVUHbEGKd4yV8WZ1/Jc9Re4bDC1piQfQVoH04/PGBcEz7wcOGg2MfQwj8LCkHCknDkHJpVvuBPj+2mnf+X7R5NkK9mMoPRk3gOz4cVx/vxR4ECjhvzHC9pRmICGujo7Dt8Ce8qVq9d2uRFDgsKk6enM4Ih9pGRJzs+ublfDHF19fO04VnvCU6pJnsy3U7vI5aPj3gC4N+C+y5SYwd1iEzm/AQ6sDIVjh72etITNPHXyUxPrFLqab+vr1OORstfSViVTUU6dH2X/ceoiCywDgygrpuuoH9bHBFyvBSiwIhlhddrzQAAAAAAAA==,MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCAMIIHMzCCBRugAwIBAgIIYnDbwSiFECUwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazElMCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsucnUwHhcNMjQwNTI3MTMxMjAwWhcNMjkwNTI3MTMxMjAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYDVQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29yZVJTQSBTaWduZXIxIDQwOTYgYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBhbGZhYmFuay5ydTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM62+ggXZkPhAeWYqhqoFDazgSVjKOj4ZL5Alx0P1Jg6iMsA1d3ZiXBf5xGHx6xkeeyX1jlOOxK5NeFRDLXP0rmxJIKr8sgKcLxArH2LxqQ7HJHeXzmHaWRnU8jB/al+gHPVGTZmsSJWBGhxXRiwMR25LrTx7rBJ7lUDKa+Ja6y+Hbt6jdZG+dH9E004EOrIRim5aANMI9aO71eZWVZhCWMJ6mhwPv+6adUMiY16YF9ldBbQqmgtOIUELFBX + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePayrollApplicationRequest' + examples: + example: + $ref: '#/components/examples/Request' + required: true + responses: + "201": + description: Запрос принят в обработку + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePayrollApplicationResponse' + examples: + example: + $ref: '#/components/examples/Response' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/salary-project/payroll/applications/{applicationId}: + get: + tags: + - Salary-Project + summary: Получить статус зарплатной ведомости + operationId: getPayrollApplicationStatus + parameters: + - name: applicationId + in: path + required: true + schema: + maxLength: 35 + type: string + responses: + "200": + description: Успешное получение статуса + content: + application/json: + schema: + $ref: '#/components/schemas/GetPayrollApplicationResponse' + examples: + example: + $ref: '#/components/examples/Response' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /alfa-security/jp/v1/subscription-api/client/subscriptions: + get: + tags: + - AlfaSecurity + summary: Получение клиентских подписок + description: Получение информации о подписках клиента на сервисы "Альфа-Безопасность" + operationId: getClientSubscriptions + parameters: + - name: active + in: query + description: Признак возврата активных подписок + required: false + schema: + type: boolean + default: true + example: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ClientSubscriptions' + examples: + example: + $ref: '#/components/examples/GetClientSubscriptions' + "400": + description: Не переданы/переданы пустыми обязательные поля и/или их значения + не соответствуют заданному формату + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope или правами\ + \ на операцию." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + examples: + ErrorScope: + $ref: '#/components/examples/ErrorScope' + NotEnoughRightsForOperation: + $ref: '#/components/examples/NotEnoughRightsForOperation' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса/ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /logistics/jp/v1/partners/deliveries: + get: + tags: + - Logistics + summary: Получение списка доставок партнера + description: "Получение списка доставок по дате, смещению по offset и ограни\ + чению по limit." + parameters: + - name: limit + in: query + description: Размер страницы + required: false + schema: + maximum: 100 + minimum: 10 + type: integer + format: int32 + default: 10 + example: 10 + - name: dateTime + in: query + description: "Дата, для которой запрашивается список доставок. Формат: YYYY-MM-DDThh:mm:ss.SSSZ" + required: true + schema: + type: string + format: date-time + - name: offset + in: query + description: "Offset смещения для следующего запроса. Если параметр не пер\ + едан, то будет выполнена выборка с первой записи (c 0 offset)" + required: false + schema: + minimum: 0 + type: integer + format: int32 + default: 0 + example: 0 + responses: + "200": + description: Статус успешного ответа + content: + application/json: + schema: + $ref: '#/components/schemas/DeliveryPageResponse' + examples: + example: + $ref: '#/components/examples/DeliveryPageResponseExample' + "400": + description: Отсутствие обязательных параметров + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Ошибка в JWT (просрочен, отозван и т.д.)" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервера + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /api/gd/v1/channels/{channelId}/providers/{providerId}/orders/{orderId}/do/{action}: + post: + tags: + - Channel-Provider + summary: Выполнение действия над конкретным заказом + description: | + Выполняет указанное действие над конкретным заказом. Переход сущности в состояние не гарантируется. + Действие указывается в path параметре {action}, где {action} - это переменная (не отдельный ресурс). + operationId: executeOrderActionByIdUsingPOST + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: orderId + in: path + description: "Уникальный идентификатор Заказа в формате нестандартного, сж\ + атого UUIDv7 - UUIDv7.compressed. См. дополнительную документацию." + required: true + schema: + type: string + - name: action + in: path + description: | + Тип действия, выполняемого над заказом. + Каждое действие переводит заказ в соответствующее состояние: + - confirm: подтверждение Провайдером взятия Заказа в работу + - in-process: обновление неформализованного состояния Заказа + - reject: вызывается Провайдером при невозможности взятия в работу назначенного на него Заказа + - deliver: вызывается Провайдером при успешной выдаче Заказа в Order.endPoint + - cancel: вызывается Провайдером для завершения процесса отмены заказа + - cancelling-in-process: вызывается Провайдером или Владельцем заказа при необходимости остановки процесса доставки + - error: вызывается при возникновении нештатной ситуации с заказом, которая не допускает продолжение бизнес-процесса + - pickup: вызывается Провайдером при получении Посылки в Order.beginPoint + - last-mile: вызывается Провайдером при готовности выдачи Заказа + - participant-change: вызывается для изменения Participant в Order.beginPoint или Order.endPoint + - channel-change: вызывается для изменения Канала доставки Заказа. Id Провайдера нужно обязательно указывать в случае, если текущий Провайдер отсутствует в новом Канале + - provider-change: вызывается для изменения Провайдера Заказа + - renotify - вызывается для инициализации повторного уведомления получателя Провайдером. В случае если в параметре channel передано несколько каналов для связи - нужно уведомить по каждому каналу + - in-process-warning - вызывается Провайдером при возникновении проблемной ситуации с Заказом, которая не ограничивает продолжение бизнес-процесса + required: true + schema: + type: string + enum: + - confirm + - reject + - cancel + - cancelling-in-process + - error + - deliver + - in-process + - pickup + - last-mile + - participant-change + - channel-change + - provider-change + - renotify + - in-process-warning + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OrderActionDto' + example: + createdAt: 2025-09-19T13:45:00Z + type: cancellinginprocess + cancelledBy: + name: 5Post + type: provider + reason: Недоступен адрес доставки + cancelledAt: 2025-09-19T13:46:10Z + required: true + responses: + "200": + description: OK + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_action: + summary: Неверное действие + value: + error: invalid_request + error_description: "No such action name: confirm1" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + order_not_found: + summary: Заказ не найден + value: + error: not_found + error_description: Not found order by id EvNTKaXm4nonNpwhi1 + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/orders/do/{action}: + post: + tags: + - Channel-Provider + summary: Групповое выполнение действия над заказами + description: | + Выполняет указанное действие над группой заказов. Переход сущности в состояние не гарантируется. + Все действия выполняются в транзакции: или все успешно, или ни одно не выполняется. + В случае ошибки при выполнении любого действия над заказом, никакие изменения не применяются. + Ответ будет содержать словарь с ошибками для каждого заказа, который не был обработан. + Действие указывается в path параметре {action}. + operationId: executeActionToOrdersUsingPOST + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: action + in: path + description: | + Тип действия, выполняемого над заказом. + Каждое действие переводит заказ в соответствующее состояние: + - confirm: подтверждение Провайдером взятия Заказа в работу + - in-process: обновление неформализованного состояния Заказа + - reject: вызывается Провайдером при невозможности взятия в работу назначенного на него Заказа + - deliver: вызывается Провайдером при успешной выдаче Заказа в Order.endPoint + - cancel: вызывается Провайдером для завершения процесса отмены заказа + - cancelling-in-process: вызывается Провайдером или Владельцем заказа при необходимости остановки процесса доставки + - error: вызывается при возникновении нештатной ситуации с заказом, которая не допускает продолжение бизнес-процесса + - pickup: вызывается Провайдером при получении Посылки в Order.beginPoint + - last-mile: вызывается Провайдером при готовности выдачи Заказа + - participant-change: вызывается для изменения Participant в Order.beginPoint или Order.endPoint + - channel-change: вызывается для изменения Канала доставки Заказа. Id Провайдера нужно обязательно указывать в случае, если текущий Провайдер отсутствует в новом Канале + - provider-change: вызывается для изменения Провайдера Заказа + - renotify - вызывается для инициализации повторного уведомления получателя Провайдером. В случае если в параметре channel передано несколько каналов для связи - нужно уведомить по каждому каналу + - in-process-warning - вызывается Провайдером при возникновении проблемной ситуации с Заказом, которая не ограничивает продолжение бизнес-процесса + required: true + schema: + type: string + enum: + - confirm + - reject + - cancel + - cancelling-in-process + - error + - deliver + - in-process + - pickup + - last-mile + - participant-change + - channel-change + - provider-change + - renotify + - in-process-warning + requestBody: + content: + application/json: + schema: + type: object + additionalProperties: + $ref: '#/components/schemas/OrderActionDto' + description: "Ключи — orderId, значения — тело action" + examples: + multipleOrders: + summary: Пример с несколькими заказами + value: + EC7UYFCYYbGELNFwv: + createdAt: 2025-09-19T13:45:00Z + type: cancellinginprocess + cancelledBy: + name: 5Post + type: provider + reason: Недоступен адрес доставки + cancelledAt: 2025-09-19T13:46:10Z + EC7UYFCYYbGELNF34: + createdAt: 2025-09-19T13:45:00Z + type: cancellinginprocess + cancelledBy: + name: 5Post + type: provider + reason: Недоступен адрес доставки + cancelledAt: 2025-09-19T13:46:10Z + EC7UYFCYYbGE52532: + createdAt: 2025-09-19T13:45:00Z + type: cancellinginprocess + cancelledBy: + name: 5Post + type: provider + reason: Недоступен адрес доставки + cancelledAt: 2025-09-19T13:46:10Z + required: true + responses: + "200": + description: OK + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_action: + summary: Неверное действие + value: + error: invalid_request + error_description: "No such action name: confirm1" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + orders_not_found: + summary: Заказы не найдены + value: + error: not_found + error_description: "Not found order by ids EvNTKaXm4nonNpwhi1,\ + \ AmNTKaXm4nonNpwhi2" + unknown_endpoint: + summary: Эндпоинт не найден или неактивен + value: + error: unknown_endpoint + error_description: Endpoint is not found or not active + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/locations: + get: + tags: + - Channel-Provider + summary: Получение всех локаций провайдера + description: | + Метод микросервиса предназначен для получения локаций провайдера. Если локации не найдены - вернется пустой массив. + operationId: getLocationsUsingGET + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: since + in: query + description: | + Идентификатор локации, относительно которого возвращается count элементов в направлении direction + - Если параметр не передан, то вернется первые count локаций, упорядоченные во времени (от старых к новым), параметр direction не учитывается + - Если count также не передан, то вернутся первые 10 локаций, упорядоченные во времени (от старых к новым). + required: false + schema: + type: string + - name: count + in: query + description: | + Количество элементов, которое нужно вернуть + - Минимальное значение - 1 + - Максимальное значение - 1000 + required: false + schema: + type: integer + format: int32 + default: 10 + - name: direction + in: query + description: | + Указывает, вернуть предыдущие записи или следующие + - Если передано значение direction = next, то возвращается count локаций, идентификаторы которых > since + - Если передано значение direction = prev, то возвращается count локаций, идентификаторы которых < since + required: false + schema: + type: string + default: next + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ProviderLocationDto' + examples: + locations_list: + summary: Локации успешно получены + value: + - id: 018f3a9d-8b8b-7234-8665-cd32ef189a21 + type: parcel_locker + name: Постамат 5Post + address: "г. Москва, ул. Тверская, д. 1" + coordinates: + latitude: 55.751244 + longitude: 37.618423 + description: Постамат на Тверской + externalId: 557ec28c-cf2b-4c6c-9603-33619d3c68d5 + - id: 158f3a9d-8b8b-7234-8665-cd32ef189a22 + type: shop + name: Магазин 5Post + address: "г. Москва, ул. Тверская, д. 3" + coordinates: + latitude: 55.751245 + longitude: 37.618426 + description: Магазин на Тверской + externalId: 997ec28c-cf2b-4c6c-9603-33619d3c6851 + empty_locations: + summary: Локации не найдены + value: [] + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_count: + summary: Неверный параметр count + value: + error: invalid_request + error_description: "Параметр count должен быть целым числом (п\ + олучено: 'dfgs')" + invalid_direction: + summary: Неверный параметр direction + value: + error: invalid_request + error_description: "Параметр direction должен быть 'next' или\ + \ 'prev' (получено: 'иваыи')" + count_exceeded: + summary: Превышено максимальное значение count + value: + error: invalid_request + error_description: "getLocations.count: must be less than or equal\ + \ to 1000" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + post: + tags: + - Channel-Provider + summary: Создание локации провайдером + operationId: createLocationsUsingPOST + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + requestBody: + content: + application/json: + schema: + maxItems: 1000 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/ProviderLocationDto' + example: + - type: parcel_locker + name: Центральный район + address: "г. Москва, ул. Тверская, д. 1" + coordinates: + latitude: 55.751244 + longitude: 37.618423 + description: string + externalId: 557ec28c-cf2b-4c6c-9603-33619d3c68d5 + - type: shop + name: Центральный район + address: "г. Москва, ул. Тверская, д. 3" + coordinates: + latitude: 55.751245 + longitude: 37.618426 + description: string + externalId: 997ec28c-cf2b-4c6c-9603-33619d3c6851 + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ProviderLocationDto' + example: + - id: 018f3a9d-8b8b-7234-8665-cd32ef189a21 + type: parcel_locker + name: Центральный район + address: "г. Москва, ул. Тверская, д. 1" + coordinates: + latitude: 55.751244 + longitude: 37.618423 + description: string + externalId: 557ec28c-cf2b-4c6c-9603-33619d3c68d5 + - id: 158f3a9d-8b8b-7234-8665-cd32ef189a22 + type: shop + name: Центральный район + address: "г. Москва, ул. Тверская, д. 3" + coordinates: + latitude: 55.751245 + longitude: 37.618426 + description: string + externalId: 997ec28c-cf2b-4c6c-9603-33619d3c6851 + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + validation_errors: + summary: Ошибки валидации данных + value: + error: invalid_request + error_description: "Параметр 0.coordinates.latitude должен быт\ + ь числом с плавающей точкой (получено: 'qwe')" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/locations/do/{action}: + post: + tags: + - Channel-Provider + summary: Выполнение указанного действия над локациями + description: | + Метод микросервиса предназначен для выполнения указанного действия над локацией. Возможные действия (action): activate: активировать локацию, deactivate: деактивировать локацию. + operationId: executeLocationActionUsingPOST + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: action + in: path + description: "Тип действия, выполняемого над локацией" + required: true + schema: + type: string + enum: + - activate + - deactivate + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/LocationIds' + example: + ids: + - 018f3a9c-7a7a-7000-8000-7a7a7a7a7a7a + - 018f3a9d-8b8b-7234-8665-cd32ef189a21 + - 018f3a9e-9c9c-7567-9123-45ab67cd89ef + required: true + responses: + "200": + description: OK + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_action: + summary: Неверное действие + value: + error: invalid_request + error_description: "No such action name: confirm1" + inactive_channel: + summary: Локации недоступны для провайдера + value: + error: invalid_request + error_description: "Not found all location ids [018f3a9d-8b8b-7234-8665-cd32ef189a21,\ + \ 018f3a9d-8b8b-7234-8665-cd32ef189a22] for provider 6" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + locations_not_found: + summary: Локации не найдены + value: + error: not_found + error_description: "Not found location by ids fkjdfjkfsk, alkgglka" + unknown_endpoint: + summary: Эндпоинт не найден или неактивен + value: + error: unknown_endpoint + error_description: Endpoint is not found or not active + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/orders: + get: + tags: + - Channel-Provider + summary: Получить список заказов + description: | + Возвращает список заказов с момента указанного ID с ограничением по лимитам + Если провайдер или канал не активен, то будут возвращены только назначенные на провайдера заказы. + operationId: getOrdersUsingGET + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: since + in: query + description: | + Идентификатор заказа, относительно которого возвращается count элементов в направлении direction + - Если параметр не передан, то вернется первые count заказов, упорядоченные во времени (от старых к новым), параметр direction не учитывается + - Если count также не передан, то вернутся первые 10 заказов, упорядоченные во времени (от старых к новым). + required: false + schema: + type: string + - name: fullHistory + in: query + description: | + Флаг для получения полной истории состояний заказа. + - true: возвращает все состояния в хронологическом порядке + - false (по умолчанию): возвращает только текущее актуальное состояние (actual=true) Использование fullHistory=false экономит трафик и ускоряет запросы к базе данных. + required: false + schema: + type: boolean + default: false + - name: count + in: query + description: | + Количество элементов, которое нужно вернуть + - Минимальное значение - 1 + - Максимальное значение - 1000 + required: false + schema: + type: integer + format: int32 + default: 10 + - name: direction + in: query + description: | + Указывает, вернуть предыдущие записи или следующие + - Если передано значение direction = next, то возвращается count заказов, идентификаторы которых > since + - Если передано значение direction = prev, то возвращается count заказов, идентификаторы которых < since + required: false + schema: + type: string + default: next + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/OrderDto' + examples: + orders_list: + summary: Список заказов + value: + - id: EC7UYFCYYbGELNFwv + limits: + whiteListChannelIds: + - 1 + blackListChannelIds: + - 2 + whiteListProviderIds: + - 1 + blackListProviderIds: + - 2 + parcel: + weight: 1500 + height: 100 + length: 300 + width: 200 + description: Электронные компоненты + value: 100 + amount: 4 + externalIds: + supply_order_id: 12345 + beginPoint: + locationId: 018f7c7d-0123-7f4c-8abc-1234567890ab + participant: + id: 0 + type: individual + name: string + phone: 79999999999 + email: email@gmail.com + endPoint: + locationId: 018f7c7d-0123-7f4c-8abc-1234567890ab + participant: + id: 0 + type: individual + name: string + phone: 79999999999 + email: email@gmail.com + states: + - actual: false + createdAt: 2025-08-10T10:00:00Z + type: created + initiator: + name: CustomerApp + - actual: false + createdAt: 2025-08-10T11:00:00Z + type: confirmed + providerId: 1 + channelId: 1 + confirmedAt: 2025-08-10T21:38:49.675Z + tracking: + - name: Трек номер + format: BARCODE + value: + - string + providerStateDescription: Заказ подтвержден + - actual: false + createdAt: 2025-08-10T12:00:00Z + type: rejected + rejectedBy: + name: DeliverySystem + type: system + reason: Недоступен адрес доставки + rejectedAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T13:00:00Z + type: delivered + deliveredAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T14:00:00Z + type: cancellinginprocess + cancelledBy: + name: Customer + type: user + reason: Отмена по инициативе клиента + cancelledAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T15:00:00Z + type: cancelled + - actual: true + createdAt: 2025-08-10T16:00:00Z + type: error + message: Ошибка при обработке заказа + reportedBy: + name: System + type: system + - actual: false + createdAt: 2025-08-10T17:00:00Z + type: atlastmile + deliveredAt: 2025-08-10T21:38:49.675Z + expireAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T18:00:00Z + type: pickedup + - actual: false + createdAt: 2025-08-10T19:00:00Z + type: inprocess + providerStateDescription: Заказ в обработке + - actual: false + createdAt: 2025-08-10T20:00:00Z + type: participantchanged + beginPointParticipant: + id: 0 + type: individual + name: Иванов Иван + phone: 79999999999 + email: email@gmail.com + - actual: false + createdAt: 2025-08-10T21:00:00Z + type: providerchanged + providerId: 1 + - actual: false + createdAt: 2025-08-10T22:00:00Z + type: channelchanged + channelId: 1 + providerId: 1 + - actual: false + createdAt: 2025-08-10T23:00:00Z + type: renotified + channel: + sms: 79999999999 + email: email@gmail.com + - actual: false + createdAt: 2025-08-11T00:00:00Z + type: inprocesswarning + providerStateDescription: Детализированное описание проблемы + empty_orders: + summary: Заказы не найдены + value: [] + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_fullHistory: + summary: Неверный параметр fullHistory + value: + error: invalid_request + error_description: "Параметр fullHistory должен быть 'true' ил\ + и 'false' (получено: 'пыавпы')" + invalid_count: + summary: Неверный параметр count + value: + error: invalid_request + error_description: "Параметр count должен быть целым числом (п\ + олучено: 'dfgs')" + invalid_direction: + summary: Неверный параметр direction + value: + error: invalid_request + error_description: "Параметр direction должен быть 'next' или\ + \ 'prev' (получено: 'иваыи')" + count_exceeded: + summary: Превышено максимальное значение count + value: + error: invalid_request + error_description: "getOrders.count: must be less than or equal\ + \ to 1000" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/orders/{orderId}: + get: + tags: + - Channel-Provider + summary: Получить заказ + description: Получение заказа по его ID + operationId: getOrderUsingGET + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: orderId + in: path + description: "Уникальный идентификатор Заказа в формате нестандартного, сж\ + атого UUIDv7 - UUIDv7.compressed. См. дополнительную документацию." + required: true + schema: + type: string + - name: fullHistory + in: query + required: false + schema: + type: boolean + default: false + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/OrderDto' + example: + id: EC7UYFCYYbGELNFwv + limits: + whiteListChannelIds: + - 1 + blackListChannelIds: + - 2 + whiteListProviderIds: + - 1 + blackListProviderIds: + - 2 + parcel: + weight: 1500 + height: 100 + length: 300 + width: 200 + description: Электронные компоненты + value: 100 + amount: 4 + externalIds: + supply_order_id: 12345 + beginPoint: + locationId: 018f7c7d-0123-7f4c-8abc-1234567890ab + participant: + id: 0 + type: individual + name: Иванов Иван + phone: 79999999999 + email: email@gmail.com + endPoint: + locationId: 018f7c7d-0123-7f4c-8abc-1234567890ab + participant: + id: 0 + type: individual + name: Петров Петр + phone: 79999999999 + email: email@gmail.com + states: + - actual: false + createdAt: 2025-08-10T10:00:00Z + type: created + initiator: + name: CustomerApp + - actual: false + createdAt: 2025-08-10T11:00:00Z + type: confirmed + providerId: 1 + channelId: 1 + confirmedAt: 2025-08-10T21:38:49.675Z + tracking: + - name: Трек номер + format: BARCODE + value: + - MTIzNDU2Nzg= + providerStateDescription: Заказ подтвержден + - actual: false + createdAt: 2025-08-10T12:00:00Z + type: rejected + rejectedBy: + name: DeliverySystem + type: system + reason: Недоступен адрес доставки + rejectedAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T13:00:00Z + type: delivered + deliveredAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T14:00:00Z + type: cancellinginprocess + cancelledBy: + name: Customer + type: user + reason: Отмена по инициативе клиента + cancelledAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T15:00:00Z + type: cancelled + - actual: true + createdAt: 2025-08-10T16:00:00Z + type: error + message: Ошибка при обработке заказа + reportedBy: + name: System + type: system + - actual: false + createdAt: 2025-08-10T17:00:00Z + type: atlastmile + deliveredAt: 2025-08-10T21:38:49.675Z + expireAt: 2025-08-10T21:38:49.675Z + - actual: false + createdAt: 2025-08-10T18:00:00Z + type: pickedup + - actual: false + createdAt: 2025-08-10T19:00:00Z + type: inprocess + providerStateDescription: Заказ в обработке + - actual: false + createdAt: 2025-08-10T20:00:00Z + type: participantchanged + beginPointParticipant: + id: 0 + type: individual + name: Сидоров Алексей + phone: 79999999999 + email: email@gmail.com + - actual: false + createdAt: 2025-08-10T21:00:00Z + type: providerchanged + providerId: 1 + - actual: false + createdAt: 2025-08-10T22:00:00Z + type: channelchanged + channelId: 1 + providerId: 1 + - actual: false + createdAt: 2025-08-10T23:00:00Z + type: renotified + channel: + sms: 79999999999 + email: email@gmail.com + - actual: false + createdAt: 2025-08-11T00:00:00Z + type: inprocesswarning + providerStateDescription: Детализированное описание проблемы + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_fullHistory: + summary: Неверный параметр fullHistory + value: + error: invalid_request + error_description: "Параметр fullHistory должен быть 'true' ил\ + и 'false' (получено: 'пыавпы')" + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + order_not_found: + summary: Заказ не найден + value: + error: not_found + error_description: Not found order by id впв + unknown_endpoint: + summary: Эндпоинт не найден или неактивен + value: + error: unknown_endpoint + error_description: Endpoint is not found or not active + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /api/gd/v1/channels/{channelId}/providers/{providerId}/locations/{locationId}: + get: + tags: + - Channel-Provider + summary: Получение локации провайдера + operationId: getLocationUsingGET + parameters: + - name: channelId + in: path + description: Уникальный идентификатор канала доставки + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: providerId + in: path + description: Уникальный идентификатор провайдера + required: true + schema: + minimum: 1 + type: integer + format: int64 + example: 1 + - name: locationId + in: path + description: Уникальный идентификатор локации в формате UUIDv7 + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ProviderLocationDto' + example: + id: 018f3a9d-8b8b-7234-8665-cd32ef189a21 + type: parcel_locker + name: Центральный район + address: "г. Москва, ул. Тверская, д. 1" + coordinates: + latitude: 55.751244 + longitude: 37.618423 + description: string + externalId: 557ec28c-cf2b-4c6c-9603-33619d3c68d5 + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + invalid_token: + summary: Токен просрочен + value: + error: invalid_token + error_description: "The access token provided is expired, revoked,\ + \ malformed, or invalid for other reasons" + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + location_not_found: + summary: Локация не найдена + value: + error: not_found + error_description: Not found location by id fkjdfjkfsk + unknown_endpoint: + summary: Эндпоинт не найден или неактивен + value: + error: unknown_endpoint + error_description: Endpoint is not found or not active + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorDto' + examples: + internal_error: + summary: Внутренняя ошибка сервера + value: + error: internal_error + error_description: Internal server error + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /aff/jp/v1/creditors/compliance: + summary: Проверка комплаенса контрагента + description: Метод для проверки контрагента на комплаенс + get: + tags: + - Aff-integration + summary: Получение результата проверки клиента + operationId: checkSoftCompanyByInn + parameters: + - name: inn + in: query + description: ИНН Кредитора + required: true + schema: + type: string + - name: name + in: query + description: Наименование Кредитора + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ComplianceResponse' + examples: + example: + $ref: '#/components/examples/ComplianceResponse' + "400": + description: Отсутствие заголовков или неверные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/registers/{registerId}/documents: + summary: Получение документов реестра + description: Метод для получения документов реестра по переданному идентификатору + get: + tags: + - Aff-integration + summary: Получение зип архива файлов + operationId: downloadRegisterZip + parameters: + - name: registerId + in: path + description: Идентификатор реестра + required: true + schema: + $ref: '#/components/schemas/requestUuid_1' + responses: + "200": + description: Successful download of archive + content: + application/zip: + schema: + type: string + format: binary + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Ендпоинт или запрашиваемый объект не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/payments/{paymentId}: + summary: Проверить существование платежа и передать его статус + description: Метод проверяет существование платежа с переданным идентификатором + и возвращает его статус + get: + tags: + - Aff-integration + summary: Получение статуса платежа + operationId: getPaymentStatus + parameters: + - name: paymentId + in: path + description: Идентификатор платежа + required: true + schema: + $ref: '#/components/schemas/requestUuid_1' + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentStatusResponse' + examples: + example: + $ref: '#/components/examples/StatusResponse' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Ендпоинт или запрашиваемый объект не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/payments: + summary: Создать платежные поручения + description: "Метод создает платежные поручения на основании массива исходных\ + \ данных, полученных во входных параметрах" + post: + tags: + - Aff-integration + summary: Сохранение платежного поручения + operationId: save + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePaymentRequest' + examples: + example: + $ref: '#/components/examples/CreatePaymentRequest' + required: true + responses: + "201": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/SavePaymentResponse' + examples: + example: + $ref: '#/components/examples/SavePaymentResponse' + "400": + description: Отсутствие заголовков или неверные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/registers/{registerId}: + summary: Проверить существование реестра и передать его статус + description: Метод проверяет существование реестра с переданным идентификатором + и возвращает его статус + get: + tags: + - Aff-integration + summary: Получение статуса реестра + operationId: getRegisterStatus + parameters: + - name: registerId + in: path + description: Идентификатор реестра + required: true + schema: + $ref: '#/components/schemas/requestUuid_1' + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterStatusResponse' + examples: + example: + $ref: '#/components/examples/StatusResponse' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Ендпоинт или запрашиваемый объект не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/registers: + summary: Создать реестр поручений + description: Метод принимает платежное поручение и отдает id реестра + post: + tags: + - Aff-integration + summary: Создать реестр поручений + operationId: create + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRegisterRequest' + examples: + example: + $ref: '#/components/examples/CreateRegisterRequest' + required: true + responses: + "201": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/SaveRegisterResponse' + examples: + example: + $ref: '#/components/examples/SaveRegisterResponse' + "400": + description: Отсутствие заголовков или неверные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /aff/jp/v1/registers/sign: + summary: Подписание реестра + description: "Метод подписывает реестр, проверяет корректность подписи и отпра\ + вляет результат" + post: + tags: + - Aff-integration + summary: Подписание реестра + operationId: sign + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SignRegisterRequest' + examples: + example: + $ref: '#/components/examples/SignRegisterRequest' + required: true + responses: + "200": + description: The registry has been successfully signed and sent for funding + content: + application/json: + schema: + $ref: '#/components/schemas/SignRegisterResponse' + examples: + example: + $ref: '#/components/examples/SignRegisterResponse' + "400": + description: Отсутствие заголовков или неверные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Ендпоинт или запрашиваемый объект не найден + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + /pp/v1/orders: + put: + tags: + - Business Lounge + summary: Изменение информации о статусе заказа на списание лимитов проходов + в БЗ + operationId: updateOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrderRequest' + required: true + responses: + "200": + description: Успешное изменение информации о статусе заказа + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrderResponse' + examples: + example: + $ref: '#/components/examples/UpdateOrderResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + post: + tags: + - Business Lounge + summary: Создание заказа на списание лимитов проходов в БЗ по запросу от внешнего + партнера + operationId: createOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateOrderRequest' + required: true + responses: + "201": + description: Успешное создание заказа на списание лимитов проходов + content: + application/json: + schema: + $ref: '#/components/schemas/CreateOrderResponse' + examples: + example: + $ref: '#/components/examples/CreateOrderResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "424": + description: Недостаточно кол-во лимитов для осуществления компенсации + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorLowBalance' + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /pp/v1/balance: + get: + tags: + - Business Lounge + summary: "Получение кол-ва лимитов клиента по проходам в БЗ, доступных для с\ + писания на данный момент" + operationId: getBalance + responses: + "200": + description: Успешное получение кол-ва лимитов клиента + content: + application/json: + schema: + $ref: '#/components/schemas/GetBalanceResponse' + examples: + example: + $ref: '#/components/examples/GetBalanceResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /pp/v1/lounge-reports: + post: + tags: + - Business Lounge + summary: "Передача факта посещения БЗ, vip-lounge, пользование услугой fasttrack" + operationId: createLoungeReport + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateLoungeReportRequest' + examples: + example: + $ref: '#/components/examples/CreateLoungeReportRequest' + required: true + responses: + "201": + description: "Успешная передача факта посещения БЗ, vip-lounge либо поль\ + зование услугой fasttrack" + content: + application/json: + schema: + $ref: '#/components/schemas/LoungeReportResponse' + examples: + example: + $ref: '#/components/examples/LoungeReportResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /dfa/gd/v1/dfa-profile/initial-placement-list: + get: + tags: + - DFA + summary: Получения списка первичных размещений ЦФА + description: Получения списка первичных размещений ЦФА + operationId: getInitialPlacementList + parameters: + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: sort + in: query + description: "Порядок сортировки в формате <имя_поля,asc|desc>. Допустимо\ + \ указать несколько значений" + required: false + schema: + type: array + items: + type: string + example: + - "dfaName,desc" + - name: customerType + in: query + description: | + Тип инвестора. Возможные значения: + * `PERSON` - физическое лицо; + * `COMPANY` - юридическое лицо + required: false + schema: + type: string + example: PERSON + - name: dfaName + in: query + description: Параметр фильтрации по наименованию ЦФА + required: false + schema: + type: string + example: NRD-DT-080324-0100 + - name: dfaRedemptionDate + in: query + description: Параметр фильтрации по дате погашения ЦФА + required: false + schema: + type: string + format: date + example: 2024-04-30 + - name: dfaParValue + in: query + description: Параметр фильтрации по стоимости ЦФА + required: false + schema: + type: integer + format: int64 + example: 100000 + - name: dfaType + in: query + description: Параметр фильтрации по типу ЦФА + required: false + schema: + type: string + example: MONEY_CLAIM + - name: dfaRateAmount + in: query + description: Параметр фильтрации по процентной ставке ЦФА + required: false + schema: + type: string + example: "1" + - name: companyIssuerName + in: query + description: Параметр фильтрации по наименованию эмитента + required: false + schema: + type: string + example: Акционерное общество "Альфа банк" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/getInitialPlacementListResponse' + examples: + example: + $ref: '#/components/examples/getInitialPlacementListResponse' + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "403": + description: Forbidden + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "409": + description: Conflict + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "429": + description: Too Many Requests + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "503": + description: Service Unavailable + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + /gd/v1/crypto-service/certificates: + get: + tags: + - Crypto-Service + summary: Получение сертификатов подписи / шифрования + responses: + "200": + description: Успешный результат + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseCertificates' + examples: + example: + $ref: '#/components/examples/responseGetCertificates' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + post: + tags: + - Crypto-Service + summary: Загрузка сертификата шифрования + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestAddCertificate' + examples: + example: + $ref: '#/components/examples/requestAddCertificate' + responses: + "201": + description: Сертификат успешно загружен + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseCertificate' + examples: + example: + $ref: '#/components/examples/responseAddCertificate' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /gd/v1/crypto-service/certificates/{id}: + patch: + tags: + - Crypto-Service + summary: Обновление сертификата шифрования + parameters: + - name: id + in: path + description: Идентификатор сертификата + required: true + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RequestChangeCertificate' + examples: + example: + $ref: '#/components/examples/requestChangeCertificate' + responses: + "200": + description: Статус сертификата успешно обновлен + headers: + x-traceid: + description: Идентификатор трассировки запроса + schema: + type: string + example: a57610880b621435 + content: + application/json: + schema: + $ref: '#/components/schemas/ResponseCertificate' + examples: + example: + $ref: '#/components/examples/responseChangeCertificate' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /claims/pp/v1/claims/{claimId}: + put: + tags: + - Claims + summary: Передать обработанное обращение в Банк + description: Передача обработанного на стороне Партнера обращения + operationId: CreateResolvedClaim + parameters: + - name: claimId + in: path + description: Идентификатор обращения в Банке + required: true + schema: + type: string + example: A2504090003 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/claims-resolved' + examples: + example: + $ref: '#/components/examples/claims-resolved' + required: true + responses: + "200": + description: Обращение передано + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + security: + - bearerAuth: [] + /order-core/pp/v1/travel/orders: + post: + tags: + - Order-Core + summary: Создание нового заказа Travel + operationId: CreateTravelOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateTravelOrder_request' + examples: + example: + $ref: '#/components/examples/CreateOrderTravelRequest' + required: true + responses: + "201": + description: Заказ создан + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseCreateOrder' + examples: + example: + $ref: '#/components/examples/SuccessResponseCreateOrder' + "200": + description: Заказ уже создан + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseAlreadyOrder' + examples: + example: + $ref: '#/components/examples/SuccessResponseAlreadyOrder' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - travelorder + /order-core/pp/v1/afisha/orders: + post: + tags: + - Order-Core + summary: Создание нового заказа Afisha + operationId: CreateAfishaOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAfishaOrder_request' + examples: + example: + $ref: '#/components/examples/CreateOrderAfishaRequest' + required: true + responses: + "201": + description: Заказ создан + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseCreateOrder' + examples: + example: + $ref: '#/components/examples/SuccessResponseCreateOrder' + "200": + description: Заказ уже создан + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseAlreadyOrder' + examples: + example: + $ref: '#/components/examples/SuccessResponseAlreadyOrder' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - afishaorder + /order-core/pp/v1/travel/orders/{orderId}: + put: + tags: + - Order-Core + summary: Обновление заказа Travel + operationId: UpdateTravelOrder + parameters: + - name: orderId + in: path + description: Идентификатор заказа в банке + required: true + schema: + type: string + example: s-5555 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateTravelOrder_request' + examples: + example: + $ref: '#/components/examples/UpdateOrderTravelRequest' + required: true + responses: + "200": + description: Заказ обновлен + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "422": + description: Некорректный статус заказа + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorIncorrectStatus' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - travelorder + /order-core/pp/v1/orders/{orderId}/confirmations: + post: + tags: + - Order-Core + summary: Подтверждение заказа + operationId: ConfirmationBankOrder + parameters: + - name: orderId + in: path + description: Идентификатор заказа в банке + required: true + schema: + type: string + example: s-5555 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PostConfirmationRequest' + examples: + example: + $ref: '#/components/examples/ConfirmationRequest' + responses: + "201": + description: Заказ подтвержден + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseConfirmOrder' + examples: + example: + $ref: '#/components/examples/SuccessResponseConfirmationOrder' + "200": + description: Заказ был подтвержден ранее + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessConfirmAlreadyOrder' + examples: + example: + $ref: '#/components/examples/SuccessConfirmAlreadyOrder' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "422": + description: Некорректный статус заказа + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorIncorrectStatus' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - coreorders + /order-core/pp/v1/orders/{orderId}: + patch: + tags: + - Order-Core + summary: Деактивация заказа + operationId: DeactivateBankOrder + parameters: + - name: orderId + in: path + description: Идентификатор заказа в банке + required: true + schema: + type: string + example: s-5555 + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchDeactivateRequest' + examples: + example: + $ref: '#/components/examples/PatchDeactivateRequest' + responses: + "204": + description: Заказ деактивирован + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - coreorders + /order-core/pp/v1/bonus-accounts: + get: + tags: + - Order-Core + summary: Получение баланса + operationId: GetBonusAccounts + responses: + "200": + description: Успешный ответ баланса бонусных счетов + content: + application/json: + schema: + $ref: '#/components/schemas/SuccessResponseBonus' + examples: + example: + $ref: '#/components/examples/SuccessResponseBonus' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + \ ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Route не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "502": + description: Неуспешный ответ + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadGateway' + security: + - bearerAuth: + - coreorders + /jp/v1/self-encashment/registries: + post: + tags: + - Self-encashment + summary: Создание реестра раскассировки + operationId: createSelfEncashmentRegistry + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PostRegistriesRequest' + examples: + example: + $ref: '#/components/examples/createRegistryRequest' + responses: + "201": + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/PostRegistriesResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/self-encashment/registries/cancel: + post: + tags: + - Self-encashment + summary: Пакетная отмена реестров раскассировки + operationId: cancelSelfEncashmentRegistries + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CancelRegistriesRequest' + examples: + example: + $ref: '#/components/examples/cancelRegistriesRequest' + responses: + "202": + description: Accepted + content: + application/json: + schema: + $ref: '#/components/schemas/CancelRegistriesResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /jp/v1/self-encashment/adm: + get: + tags: + - Self-encashment + summary: Получение информации об АДМ по их идентификаторам + operationId: getAdmDevicesInfo + parameters: + - name: admPids + in: query + description: "Идентификаторы АДМ через запятую. Если не переданы, то возвр\ + ащается информация по всем устройствам." + required: false + explode: false + schema: + maxItems: 100 + type: array + items: + pattern: "^\\d{8}$" + type: string + example: + - "00330456" + - "00349012" + - name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + - name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GetAdmResponse' + examples: + example: + $ref: '#/components/examples/getAdmResponse' + "400": + description: Неверные входные параметры запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам." + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "409": + description: Конфликт + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorConflict' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Внутренняя ошибка сервиса при выполнении обработки запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /partner/jp/v1/individuals: + get: + tags: + - Partner + summary: Получение заявок ИП + parameters: + - name: fromDate + in: query + description: Начало интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-01T00:00:00.001Z + - name: toDate + in: query + description: Конец интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-31T23:59:59.999Z + - name: limit + in: query + description: Параметр пагинации - Запрашиваемое кол-во элементов на странице + required: false + schema: + type: integer + - name: offset + in: query + description: Параметр пагинации - Смещение от начала + required: false + schema: + type: integer + - name: sort + in: query + description: "Сортировка по полю и направлению. Формат: поле,направление.\ + \ Доступные поля: createdAt, updatedAt. Доступные направления: asc (по в\ + озрастанию), desc (по убыванию)." + required: false + schema: + pattern: "^(createdAt|updatedAt),(asc|desc)$" + type: string + example: "createdAt,asc" + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/IndividualsPage' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + post: + tags: + - Partner + summary: Создание заявки ИП + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateIndividualRequest' + examples: + create: + $ref: '#/components/examples/create_individual_example' + required: true + responses: + "201": + description: Создано + headers: + Location: + schema: + type: string + format: uri + content: + application/json: + schema: + $ref: '#/components/schemas/CreatedIndividualId' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + security: + - bearerAuth: [] + /partner/jp/v1/individuals/{individualId}: + get: + tags: + - Partner + summary: Получение заявки ИП по ID + parameters: + - name: individualId + in: path + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/IndividualLead' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + /partner/jp/v1/llcs: + get: + tags: + - Partner + summary: Получение заявок ООО + parameters: + - name: fromDate + in: query + description: Начало интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-01T00:00:00.001Z + - name: toDate + in: query + description: Конец интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-31T23:59:59.999Z + - name: limit + in: query + description: Параметр пагинации - Запрашиваемое кол-во элементов на странице + required: false + schema: + type: integer + - name: offset + in: query + description: Параметр пагинации - Смещение от начала + required: false + schema: + type: integer + - name: sort + in: query + description: "Сортировка по полю и направлению. Формат: поле,направление.\ + \ Доступные поля: createdAt, updatedAt. Доступные направления: asc (по в\ + озрастанию), desc (по убыванию)." + required: false + schema: + pattern: "^(createdAt|updatedAt),(asc|desc)$" + type: string + example: "createdAt,asc" + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/LlcsPage' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + post: + tags: + - Partner + summary: Создание заявки ООО + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateLlcRequest' + examples: + create: + $ref: '#/components/examples/create_llc_example' + required: true + responses: + "201": + description: Создано + headers: + Location: + schema: + type: string + format: uri + content: + application/json: + schema: + $ref: '#/components/schemas/CreatedLlcId' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "415": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/Error_2' + security: + - bearerAuth: [] + /partner/jp/v1/llcs/{llcId}: + get: + tags: + - Partner + summary: Получение заявки ООО по ID + parameters: + - name: llcId + in: path + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/LlcLead' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + /partner/jp/v1/manager-cities: + get: + tags: + - Partner + summary: Получение списка городов присутствия менеджеров + parameters: + - name: limit + in: query + description: Параметр пагинации - Запрашиваемое кол-во элементов на странице + required: false + schema: + type: integer + - name: offset + in: query + description: Параметр пагинации - Смещение от начала + required: false + schema: + type: integer + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ManagerCitiesPage' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + /partner/jp/v1/clients-inn: + get: + tags: + - Partner + summary: Список ИНН клиентов с продажами за месяц по выбранным продуктам + parameters: + - name: month + in: query + description: Отчётный месяц (ISO 8601). Не старше 6 месяцев от текущей даты. + required: true + style: form + explode: false + schema: + $ref: '#/components/schemas/MonthPeriod' + example: 2025-08-01T00:00:00.000Z + - name: productCode + in: query + description: Код продукта. Допускается передача только одного значения. + required: true + style: form + explode: false + schema: + type: string + example: DEBIT_CARD + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ClientsResponse' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + /partner/jp/v1/sales: + get: + tags: + - Partner + summary: Список успешно проданных продуктов по ИНН за указанный месяц + parameters: + - name: month + in: query + description: Отчётный месяц (ISO 8601). Не старше 6 месяцев от текущей даты. + required: true + style: form + explode: false + schema: + $ref: '#/components/schemas/MonthPeriod' + example: 2025-08-01T00:00:00.000Z + - name: inn + in: query + description: ИНН ЮЛ + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/SalesResponse' + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + security: + - bearerAuth: [] + /mathmod-scorings/jp/v1/compliance: + get: + tags: + - Mathmod scorings + summary: Получить оценку организации + description: Метод получения уровня благонадежности организации по комплаенс-мерам + operationId: getComplianceScore + parameters: + - name: inn + in: query + description: ИНН организации + required: true + schema: + maxLength: 12 + minLength: 10 + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ComplianceScoreResponse' + examples: + example: + $ref: '#/components/examples/getComplianceScoreResponse' + "400": + description: Некорректная структура запроса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: "Предоставленный токен просрочен, отозван, имеет неправильн\ + ый формат или недействителен по другим причинам" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: У пользователя нет прав на использование запрашиваемого сервиса + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: "Эндпоинт не найден, либо по указанному ИНН не найдена комп\ + ания" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервер временно недоступен + /rates/gd/v1/offices-rates: + get: + tags: + - Offices-rates + summary: Получить курсы валют по офисам + responses: + "200": + description: Успешный ответ с курсами валют + content: + application/json: + schema: + type: object + examples: + example: {} + "400": + description: Неверные входные параметры запроса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + "401": + description: Токен недействителен. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorUnauthorized' + "403": + description: "У пользователя нет прав на использование запрашиваемого се\ + рвиса, доступ к которому не предусмотрен настройками scope" + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorScope' + "404": + description: Эндпоинт не найден или неактивен + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorNotFound' + "429": + description: Cлишком много запросов в заданный период времени + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' + "500": + description: Внутренняя ошибка сервиса. + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternal' + "503": + description: Сервис временно недоступен + content: + application/json: + schema: + $ref: '#/components/schemas/Error_1' +components: + schemas: + TokenRequest: + required: + - client_id + - client_secret + - grant_type + type: object + properties: + grant_type: + type: string + description: Тип гранта + example: authorization_code + enum: + - authorization_code + - refresh_token + - client_credentials + code: + type: string + description: Код авторизации + format: uuid + example: 8962c304-89b1-11ec-a8a3-0242ac120002 + client_id: + type: string + description: Идентификатор партнерского сервиса + format: uuid + example: 0cee0683-85ae-49f2-a63d-29f97aad1911 + client_secret: + type: string + description: Секретный ключ партнерского сервиса + example: Qwerty1234567890Qwerty1234567890! + redirect_uri: + type: string + description: URI перенаправления + example: https://wwww.partner.ru/code + refresh_token: + type: string + description: Токен обновления + format: uuid + example: 13b8230b-b6bf-4bb9-b977-3bc0a988a5fd + code_verifier: + type: string + description: Код верификатор + scope: + type: string + description: Область применения + example: loan-applications + TokenResponse: + required: + - access_token + - refresh_token + - token_type + type: object + properties: + access_token: + type: string + description: Токен доступа + example: eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsInNjb3BlX3NlcnZpY2VzIjpbInBheW1lbnQiLCJzdGF0ZW1lbnQiXSwiaWF0IjoxNjMxNjYzMDYzLCJzY29wZV9jbGFpbXMiOlsibmFtZSIsImdpdmVuX25hbWUiLCJmYW1pbHlfbmFtZSIsIm1pZGRsZV9uYW1lIiwiZW1haWwiLCJwaG9uZV9udW1iZXIiXX0.RZ98I-PT_HGMzc7IbwGvlZjLOYuInta6pczEc_h4yCvZKCafIqs4ZBbs7eSY3NpXGzTbSZkGQA9wfX2NFDXZelwyNTooFQMpXzytrEhLww05H8ZFCH0kEQ_IpnJk-KeYkBLD0Oa75Gi6Lqj-Dr8KoX4Zq93ZyT4sr7Hzb1H287UlkJWVlpz_E7slLIob8m3keGbDysNyEBKJzsPcW27HENZBnvYwdE1pzwB8ObEZkICO8kbEP7MupLbhFyjxJFlI6Bq2DNjqi_QgQzvjvpD4KILxDms-Upg8h6GptYyoOl1BMGfN7WhN2vOUFYNuivNKctwcfD_H73kHJGu5KIJmGA + refresh_token: + type: string + description: Токен обновления + format: uuid + example: 13b8230b-b6bf-4bb9-b977-3bc0a988a5fd + token_type: + type: string + description: Тип токена + example: Bearer + enum: + - Bearer + expires_in: + type: integer + description: Срок жизни токена в секундах + example: 3600 + id_token: + type: string + description: Идентификационный токен + example: eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY3IiOiJMb0EzIiwiYXpwIjoiMGNlZTA2ODMtODVhZS00OWYyLWE2M2QtMjlmOTdhYWQxOTExIiwiYXV0aF90aW1lIjoxNjMxNjYzMDUzLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsImlhdCI6MTYzMTY2MzA2Mywibm9uY2UiOiJuLTBTNl9XekEyTWoifQ.xBE6LEUxOKleHCZVQacldJfKr5KtyyvJKCCmInqapmRJ_aRF-cEoVfpJd_kxlNmJYT7AcjMMppovNkmhB49VL5DK8FhF0fvRgLskKR9Eohy4eiC8ued03Z1LyLz1H7EcKSkusaCIajzIvxxZfVtSHI4jmgLg6ItXPdZgIDUWINgESkl6I7IP5CbfONHweNnbkWEOEzxDgGGnxxtPxrWVoPVP-ijUeUSH_iESHfrhY_ePRMYi2If62IsKX_0GT5BHRYOhXVDZ9fyn5fRCvg8_QoCykDVIOZMtWQ3w4TadqS0dfMlsLBxkVbVftzH2fWRLTCX3SJ5AXiytHkpow8V45w + example: + access_token: eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsInNjb3BlX3NlcnZpY2VzIjpbInBheW1lbnQiLCJzdGF0ZW1lbnQiXSwiaWF0IjoxNjMxNjYzMDYzLCJzY29wZV9jbGFpbXMiOlsibmFtZSIsImdpdmVuX25hbWUiLCJmYW1pbHlfbmFtZSIsIm1pZGRsZV9uYW1lIiwiZW1haWwiLCJwaG9uZV9udW1iZXIiXX0.RZ98I-PT_HGMzc7IbwGvlZjLOYuInta6pczEc_h4yCvZKCafIqs4ZBbs7eSY3NpXGzTbSZkGQA9wfX2NFDXZelwyNTooFQMpXzytrEhLww05H8ZFCH0kEQ_IpnJk-KeYkBLD0Oa75Gi6Lqj-Dr8KoX4Zq93ZyT4sr7Hzb1H287UlkJWVlpz_E7slLIob8m3keGbDysNyEBKJzsPcW27HENZBnvYwdE1pzwB8ObEZkICO8kbEP7MupLbhFyjxJFlI6Bq2DNjqi_QgQzvjvpD4KILxDms-Upg8h6GptYyoOl1BMGfN7WhN2vOUFYNuivNKctwcfD_H73kHJGu5KIJmGA + refresh_token: 13b8230b-b6bf-4bb9-b977-3bc0a988a5fd + id_token: eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY3IiOiJMb0EzIiwiYXpwIjoiMGNlZTA2ODMtODVhZS00OWYyLWE2M2QtMjlmOTdhYWQxOTExIiwiYXV0aF90aW1lIjoxNjMxNjYzMDUzLCJpc3MiOiJodHRwczpcL1wvaWQuYWxmYWJhbmsucnUiLCJleHAiOjE2MzE2NjY2NjMsImlhdCI6MTYzMTY2MzA2Mywibm9uY2UiOiJuLTBTNl9XekEyTWoifQ.xBE6LEUxOKleHCZVQacldJfKr5KtyyvJKCCmInqapmRJ_aRF-cEoVfpJd_kxlNmJYT7AcjMMppovNkmhB49VL5DK8FhF0fvRgLskKR9Eohy4eiC8ued03Z1LyLz1H7EcKSkusaCIajzIvxxZfVtSHI4jmgLg6ItXPdZgIDUWINgESkl6I7IP5CbfONHweNnbkWEOEzxDgGGnxxtPxrWVoPVP-ijUeUSH_iESHfrhY_ePRMYi2If62IsKX_0GT5BHRYOhXVDZ9fyn5fRCvg8_QoCykDVIOZMtWQ3w4TadqS0dfMlsLBxkVbVftzH2fWRLTCX3SJ5AXiytHkpow8V45w + token_type: Bearer + expires_in: 3600 + TokenError: + required: + - error + type: object + properties: + error: + type: string + description: Ошибка + example: invalid_request + error_description: + type: string + description: Описание ошибки + UserInfoError: + required: + - error + type: object + properties: + error: + type: string + description: Ошибка + example: invalid_request + error_description: + type: string + description: Описание ошибки + ClientSecretResponse: + required: + - clientId + - clientSecret + type: object + properties: + clientId: + type: string + description: Идентификатор партнерского сервиса + format: uuid + example: 0cee0683-85ae-49f2-a63d-29f97aad1911 + clientSecret: + type: string + description: Секретный ключ партнерского сервиса + example: Qwerty1234567890Qwerty1234567890! + example: + clientId: 0cee0683-85ae-49f2-a63d-29f97aad1911 + clientSecret: Qwerty1234567890Qwerty1234567890! + ClientSecretError: + required: + - error + type: object + properties: + error: + type: string + description: Ошибка + example: invalid_request + error_description: + type: string + description: Описание ошибки + RevokeRequest: + required: + - client_id + - client_secret + - token + type: object + properties: + client_id: + type: string + description: Идентификатор партнерского сервиса + format: uuid + example: 0cee0683-85ae-49f2-a63d-29f97aad1911 + client_secret: + type: string + description: Секретный ключ партнерского сервиса + example: Qwerty1234567890Qwerty1234567890! + token: + type: string + description: Отзываемый токен + token_type_hint: + type: string + description: Тип отзываемого токена + example: refresh_token + enum: + - access_token + - refresh_token + RevokeError: + required: + - error + type: object + properties: + error: + type: string + description: Ошибка + example: invalid_request + error_description: + type: string + description: Описание ошибки + ClientInfo: + required: + - category + - email + - fullName + - inn + - kpps + - ogrn + - okpo + - okved + - organizationForm + - organizationId + - phone + - registrationDate + - shortName + - status + - type + type: object + properties: + organizationId: + type: string + description: Хэш идентификатора клиента (ЮЛ) + example: bca96ae8b26184217fcf75f51347bd7bd5031ea6605c434c49f85378e9509732 + fullName: + type: string + description: Полное наименование организации + example: Общество с ограниченной ответственностью "Ромашка" + shortName: + type: string + description: Сокращённое наименование организации + example: ООО "Ромашка" + inn: + type: string + description: ИНН + example: "114693784" + organizationForm: + $ref: '#/components/schemas/ClientInfo_organizationForm' + kpps: + type: array + items: + type: string + description: Список КПП организации + example: "2427920" + ogrn: + type: string + description: ОГРН + example: "1020203094163" + okpo: + type: string + description: ОКПО + example: "41294456" + okved: + type: string + description: ОКВЭД + example: "71.12" + type: + type: string + description: Тип организации + example: LEGAL + phone: + type: string + description: Контактный телефон клиента + example: "79099876543" + email: + type: string + description: Электронная почта клиента + example: client@example.com + category: + type: string + description: Категория организации. BANK - банк; FINANCIAL - финансовая; + OTHER - другая + enum: + - BANK + - FINANCIAL + - OTHER + status: + type: string + description: Статус организации. ACTIVE — действующая; LIQUIDATING — ликвидируется; + LIQUIDATED — ликвидирована + enum: + - ACTIVE + - LIQUIDATING + - LIQUIDATED + registrationDate: + type: string + description: Дата регистрации организации + format: date-time + address: + $ref: '#/components/schemas/Address' + accounts: + type: array + items: + $ref: '#/components/schemas/Account' + example: + ogrn: "1020203094163" + organizationForm: + code: "12300" + fullName: Общество с ограниченной ответственностью + shortName: ООО + type: "2014" + address: + area: Тахтамукайский район + settlementType: г. + zip: "385600" + country: "643" + fiasCode: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + city: Майкоп + house: "3" + building: "1" + settlement: Майкоп + flat: "123" + street: улица Депутатская + fullAddress: "Республика Адыгея, г. Майкоп, улица Депутатская, д. 3" + region: Республика Адыгея + inn: "114693784" + fullName: Общество с ограниченной ответственностью "Ромашка" + type: LEGAL + okpo: "41294456" + organizationId: bca96ae8b26184217fcf75f51347bd7bd5031ea6605c434c49f85378e9509732 + phone: "79099876543" + okved: "71.12" + registrationDate: 2000-01-23T04:56:07.000+00:00 + kpps: + - "2427920" + - "2427920" + accounts: + - specConditions: + - code: AI17 + description: Счёт заблокирован + value: true + - code: AI17 + description: Счёт заблокирован + value: true + clientName: Наименование + typeName: Расчётный счёт + type: PAYMENT + amountOverdraftOwnFunds: 0.8008281904610115 + amountOverdraftLimit: 100000 + amountBalance: 810000 + amountHolds: 100 + number: "40702810002300001935" + blockedSums: + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + bank: + bic: "044525593" + transitAccountNumber: "40702978904100000001" + amountTotal: 100000 + openDate: 2021-10-07 + currencyCode: "810" + - specConditions: + - code: AI17 + description: Счёт заблокирован + value: true + - code: AI17 + description: Счёт заблокирован + value: true + clientName: Наименование + typeName: Расчётный счёт + type: PAYMENT + amountOverdraftOwnFunds: 0.8008281904610115 + amountOverdraftLimit: 100000 + amountBalance: 810000 + amountHolds: 100 + number: "40702810002300001935" + blockedSums: + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + bank: + bic: "044525593" + transitAccountNumber: "40702978904100000001" + amountTotal: 100000 + openDate: 2021-10-07 + currencyCode: "810" + shortName: ООО "Ромашка" + category: BANK + email: client@example.com + status: ACTIVE + Address: + type: object + properties: + area: + type: string + description: Район + example: Тахтамукайский район + building: + type: string + description: "Строение, корпус" + example: "1" + city: + type: string + description: Город + example: Майкоп + country: + type: string + description: Числовой код страны + example: "643" + flat: + type: string + description: Квартира + example: "123" + fullAddress: + type: string + description: Адрес + example: "Республика Адыгея, г. Майкоп, улица Депутатская, д. 3" + house: + type: string + description: Дом + example: "3" + region: + type: string + description: Полное наименование региона + example: Республика Адыгея + settlement: + type: string + description: Населенный пункт + example: Майкоп + settlementType: + type: string + description: Тип населенного пункта + example: г. + street: + type: string + description: Улица + example: улица Депутатская + zip: + type: string + description: Индекс + example: "385600" + fiasCode: + type: string + description: Код ФИАС + format: uuid + example: + area: Тахтамукайский район + settlementType: г. + zip: "385600" + country: "643" + fiasCode: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + city: Майкоп + house: "3" + building: "1" + settlement: Майкоп + flat: "123" + street: улица Депутатская + fullAddress: "Республика Адыгея, г. Майкоп, улица Депутатская, д. 3" + region: Республика Адыгея + Account: + type: object + properties: + number: + maxLength: 20 + minLength: 20 + type: string + description: Наименование счета + example: "40702810002300001935" + type: + type: string + description: Тип счёта + example: PAYMENT + typeName: + type: string + description: Наименование типа счёта + example: Расчётный счёт + openDate: + type: string + description: Дата открытия счёта + example: 2021-10-07 + currencyCode: + maxLength: 3 + minLength: 3 + type: string + description: Цифровой код валюты + example: "810" + transitAccountNumber: + type: string + description: Парный транзитный счет + example: "40702978904100000001" + specConditions: + type: array + items: + $ref: '#/components/schemas/SpecCondition' + clientName: + type: string + description: Клиентское наименование счёта + example: Наименование + amountBalance: + type: number + description: Текущий остаток по счёту в рублях(или в валюте счета) + example: 810000 + amountTotal: + type: number + description: Сумма доступных средств (без учёта овердрафта) в рублях(или + в валюте счета) + example: 100000 + amountHolds: + type: number + description: Сумма зарезервированных средств (холды) в рублях(или в валюте + счета) + example: 100 + amountOverdraftOwnFunds: + type: number + description: Собственные средства в рублях(или в валюте счета) + amountOverdraftLimit: + type: number + description: Доступный лимит средств в рублях(или в валюте счета) + example: 100000 + blockedSums: + type: array + description: Заблокированные (арестованные) суммы на счёте + items: + $ref: '#/components/schemas/AccountBlockInfo' + bank: + $ref: '#/components/schemas/Account_bank' + example: + specConditions: + - code: AI17 + description: Счёт заблокирован + value: true + - code: AI17 + description: Счёт заблокирован + value: true + clientName: Наименование + typeName: Расчётный счёт + type: PAYMENT + amountOverdraftOwnFunds: 0.8008281904610115 + amountOverdraftLimit: 100000 + amountBalance: 810000 + amountHolds: 100 + number: "40702810002300001935" + blockedSums: + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа №\ + \ 53228 от 05.11.2019 г" + sum: "988800" + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа №\ + \ 53228 от 05.11.2019 г" + sum: "988800" + bank: + bic: "044525593" + transitAccountNumber: "40702978904100000001" + amountTotal: 100000 + openDate: 2021-10-07 + currencyCode: "810" + SpecCondition: + type: object + properties: + code: + type: string + description: Код спецусловия + example: AI17 + description: + type: string + description: Описание спецусловия + example: Счёт заблокирован + value: + type: boolean + description: Текущее значение + example: true + description: Спецусловия по счету. Для AI12 - Нельзя дебетовать. AI11 - Нельзя + кредитовать. AI14 - Клиент закрыт. AI17 - Счёт заблокирован. AI20 - Неактивный + счёт. AI30 - Счёт закрыт. AI47 - Внутренний счёт. AI82 - Дебетование ограничено. + AI83 - Электронная картотека. AI87 - Бумажная разновалютная картотека. + example: + code: AI17 + description: Счёт заблокирован + value: true + AccountBlockInfo: + type: object + properties: + num: + type: string + description: Номер решения + example: "112233" + beginDate: + type: string + description: Дата начала действия ограничения + format: datetime + example: 2020-10-23 + cause: + type: string + description: Основание ареста + example: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + initiator: + type: string + description: "Наименование органа, наложившего арест" + example: Межрайонная ИФНС России № 51 по г. Москве + sum: + type: string + description: Заблокированная (арестованная) сумма на счёте в рублях(или + в валюте счета) + example: "988800" + blockType: + type: string + description: "Бухгалтерский режим, к которому относится данное решение.\ + \ OUTGOING_LIMITATION - Полная блокировка; PARTIAL_BALANCE_BLOCK - Бло\ + кировка части баланса" + example: PARTIAL_BALANCE_BLOCK + enum: + - OUTGOING_LIMITATION + - PARTIAL_BALANCE_BLOCK + description: Объект массива с информацией о блокировках счета клиента + example: + beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа № 53228\ + \ от 05.11.2019 г" + sum: "988800" + ErrorBadRequest: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_request + error_description: + type: string + description: Сообщение об ошибке + example: Authorization header is not present in request headers + description: Неверные входные параметры запроса + ErrorUnauthorized: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_token + error_description: + type: string + description: Сообщение об ошибке + example: "The access token provided is expired, revoked, malformed, or invalid\ + \ for other reasons" + description: "Предоставленный токен просрочен, отозван, имеет неправильный ф\ + ормат или недействителен по другим причинам" + ErrorScope: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: insufficient_scope + error_description: + type: string + description: Сообщение об ошибке + example: The request requires higher privileges than provided by the access + token + description: "У пользователя нет прав на использование запрашиваемого сервис\ + а, доступ к которому не предусмотрен настройками scope" + ErrorNotFound: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: unknown_endpoint + error_description: + type: string + description: Сообщение об ошибке + example: Endpoint is not found or not active + description: Эндпоинт не найден или неактивен + ErrorInternal: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: internal_error + error_description: + type: string + description: Сообщение об ошибке + example: Internal server error + description: Внутренняя ошибка сервиса при выполнении обработки запроса + Statement: + type: object + properties: + _links: + type: array + description: "Ссылки на предыдущую и следующую страницу, если они есть" + items: + $ref: '#/components/schemas/Links_inner' + transactions: + type: array + description: Массив транзакций + items: + $ref: '#/components/schemas/Transactions_inner' + description: Выписка операций по счетам + example: + _links: + - rel: prev + href: accountNumber=40702810500006103990&statementDate=2018-03-15&page=3 + - rel: prev + href: accountNumber=40702810500006103990&statementDate=2018-03-15&page=3 + transactions: + - documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + swiftTransfer: + bankOperationCode: CRED + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + transactionTypeCode: S01 + instructionCode: instructionCode + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageIdentifier: S000013082900014 + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + beneficiaryCustomerName: ООО Ромашка + instructedAmount: "USD70,00" + transactionRelatedReference: transactionRelatedReference + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + orderingInstitutionAccount: ABOCBNBJ080 + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + intermediaryBankAccount: COBADEFF + transactionReferenceNumber: 69528 + orderingInstitutionOption: D + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + senderCharges: "USD7,03" + receiverCharges: receiverCharges + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + - documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + swiftTransfer: + bankOperationCode: CRED + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + transactionTypeCode: S01 + instructionCode: instructionCode + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageIdentifier: S000013082900014 + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + beneficiaryCustomerName: ООО Ромашка + instructedAmount: "USD70,00" + transactionRelatedReference: transactionRelatedReference + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + orderingInstitutionAccount: ABOCBNBJ080 + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + intermediaryBankAccount: COBADEFF + transactionReferenceNumber: 69528 + orderingInstitutionOption: D + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + senderCharges: "USD7,03" + receiverCharges: receiverCharges + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + Links: + type: array + description: "Ссылки на предыдущую и следующую страницу, если они есть" + items: + $ref: '#/components/schemas/Links_inner' + Transactions: + type: array + description: Массив транзакций + items: + $ref: '#/components/schemas/Transactions_inner' + Amount: + type: object + properties: + amount: + type: number + description: Сумма + example: 1.01 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: USD + description: Сумма в валюте счета + example: + amount: 1.01 + currencyName: USD + AmountRub: + type: object + properties: + amount: + type: number + description: Сумма + example: 1.01 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: USD + description: Сумма в валюте счета + example: + amount: 1.01 + currencyName: USD + RurTransfer: + type: object + properties: + cartInfo: + $ref: '#/components/schemas/CartInfo' + deliveryKind: + type: string + description: Способ отправки документа + enum: + - электронно + - телеграфом + - почтой + - срочно + x-enum-varnames: + - ELECTRONICALLY + - TELEGRAPH + - POST + - URGENT + departmentalInfo: + $ref: '#/components/schemas/DepartmentalInfo' + payeeAccount: + type: string + description: Номер счёта получателя + example: "40802810401300015422" + payeeBankBic: + type: string + description: БИК банка получателя + example: "9611925" + payeeBankCorrAccount: + type: string + description: Корсчёт банка получателя + example: "30101810200000000593" + payeeBankName: + type: string + description: Наименование банка получателя + example: АО \"АЛЬФА-БАНК\" + payeeInn: + type: string + description: ИНН получателя + example: "7728168971" + payeeKpp: + type: string + description: КПП получателя + example: "770801001" + payeeName: + type: string + description: Наименование получателя + example: Наименование получателя + payerAccount: + type: string + description: Номер счёта плательщика + example: "40802810401300015422" + payerBankBic: + type: string + description: БИК банка плательщика + example: "044525593" + payerBankCorrAccount: + type: string + description: Корсчёт банка плательщика + example: "30101810200000000593" + payerBankName: + type: string + description: Наименование банка плательщика + example: АО \"АЛЬФА-БАНК\" + payerInn: + type: string + description: ИНН плательщика + example: "7728168971" + payerKpp: + type: string + description: КПП плательщика + example: "770801001" + payerName: + type: string + description: Наименование плательщика + example: Гаврилов Добрыня Петрович + payingCondition: + type: string + description: Условие оплаты (для 02) + purposeCode: + type: string + description: | + Кодовое назначение платежа * `1` - При переводе денежных средств, являющихся заработной платой и (или) иными доходами * `2` - При переводе денежных средств, являющихся доходами, на которые не может быть обращено взыскание * `3` - При переводе денежных средств, являющихся видами доходов + enum: + - "1" + - "2" + - "3" + receiptDate: + type: string + description: Дата поступления в банк плательщика + example: 2018-12-31 + valueDate: + type: string + description: Дата валютирования + example: 2018-12-31 + description: Блок для описания рублевых счетов + example: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + CartInfo: + type: object + properties: + documentCode: + type: string + description: Шифр документа (картотека) (для 16) + documentContent: + type: string + description: Содержание операции (для 16) + documentDate: + type: string + description: Дата документа (картотека) (для 16) + example: 2019-10-19T06:33:47.923Z + documentNumber: + type: string + description: Номер документа (картотека) (для 16) + paymentNumber: + type: string + description: Номер платежа (картотека) (для 16) + restAmount: + type: string + description: Сумма остатка платежа (картотека) (для 16) + description: Дополнительная информация о документе (картотека) + example: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + DepartmentalInfo: + type: object + properties: + uip: + type: string + description: Уникальный идентификатор платежа + example: "32221003200126505006" + drawerStatus101: + type: string + description: Показатель статуса налогоплательщика (реквизит - 101) + example: "1" + kbk: + type: string + description: Код бюджетной классификации (реквизит - 104) + example: "39210202010061000160" + oktmo: + type: string + description: Код OKTMO (реквизит - 105) + example: "11605000" + reasonCode106: + type: string + description: Показатель основания платежа (реквизит - 106) + example: ТП + taxPeriod107: + type: string + description: Налоговый период / код таможенного органа (реквизит - 107) + example: МС.03.2016 + docNumber108: + type: string + description: Номер налогового документа (реквизит - 108) + example: "123" + docDate109: + type: string + description: Дата налогового документа (реквизит - 109) + example: 31.12.2018 + paymentKind110: + type: string + description: ип налогового платежа (реквизит - 110) + example: "1" + description: "Реквизиты налогового, таможенного или иного бюджетного платежа" + example: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + SwiftTransfer: + type: object + properties: + bankOperationCode: + type: string + description: Код банковской операции (формат MT103) + enum: + - CRED + beneficiaryBankAccount: + type: string + description: Номер счета банка бенефициара. 1-я часть значения поля 57 в + формате MT103 + example: LOYDGB21323 + beneficiaryBankName: + type: string + description: "Код BIC, расположение или название и адрес банка бенефициа\ + ра. Содержимое поля 57 (за исключением номера счета, с разделителями)\ + \ в формате MT103" + example: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: + type: string + description: Признак вида поля банка бенефициара (поле 57 в формате MT103) + example: D + beneficiaryCustomerAccount: + type: string + description: Номер счета бенефициара. 1-я часть значения поля 59 в формате + MT103 + example: /40702810701300000761 + beneficiaryCustomerName: + type: string + description: "Код BIC/BEI или название и адрес бенефициара. Содержимое п\ + оля 59 (за исключением номера счета, с разделителями) в формате MT103" + example: ООО Ромашка + detailsOfCharges: + type: string + description: | + Сведения о расходах (формат MT103) * `OUR` - Все расходы по данной операции относятся на счет Плательщика + enum: + - OUR + exchangeRate: + type: string + description: Курс конвертации (формат MT103) + example: "67,74" + instructedAmount: + type: string + description: Валюта/сумма по инструкции (формат MT103) + example: "USD70,00" + instructionCode: + type: string + description: Код инструкции (формат MT103) + intermediaryBankAccount: + type: string + description: Номер счета банка-посредника.1-я часть значения поля 56 в формате + MT103 + example: COBADEFF + intermediaryBankName: + type: string + description: "Код BIC или название банка-посредника. Содержимое поля 56\ + \ (за исключением номера счета, с разделителями) в формате MT103" + example: АО "АЛЬФА-БАНК" + intermediaryBankOption: + type: string + description: Признак вида поля банка-посредника + example: D + messageDestinator: + type: string + description: Получатель сообщения SWIFT (формат MT103) + example: LAPBLV2X + messageIdentifier: + type: string + description: Уникальный системный номер сообщения SWIFT (формат MT103) + example: S000013082900014 + messageOriginator: + type: string + description: Отправитель сообщения SWIFT (формат MT103) + example: SABRRU2P + messageReceiveTime: + type: string + description: Дата и время получения сообщения SWIFT (формат MT103) + example: 15-05-27 13:21 + messageSendTime: + type: string + description: Дата и время отправки сообщения SWIFT (формат MT103) + example: 15-05-27 13:21 + messageType: + type: string + description: Тип сообщения SWIFT + enum: + - "103" + orderingCustomerAccount: + type: string + description: Номер счета плательщика в формате + example: /08251801040004813 + orderingCustomerName: + type: string + description: "Код BIC/BEI или название и адрес плательщика.Содержимое по\ + ля 50 (за исключением номера счета, с разделителями) в формате MT103" + example: ООО Радуга + orderingCustomerOption: + type: string + description: Признак вида поля плательщика + example: K + orderingInstitutionAccount: + type: string + description: Номер счета банка плательщика.1-я часть значения поля 52 в + формате MT103 + example: ABOCBNBJ080 + orderingInstitutionName: + type: string + description: "Код BIC или название и адрес банка плательщика. Содержимое\ + \ поля 52 (за исключением номера счета, с разделителями) в формате MT103" + example: АО "АЛЬФА-БАНК" + orderingInstitutionOption: + type: string + description: Признак вида поля банка плательщика + example: D + receiverCharges: + type: string + description: Расходы получателя (формат MT103) + receiverCorrespondentAccount: + type: string + description: Номер счета корреспондента получателя. + example: "30101810400000000000" + receiverCorrespondentName: + type: string + description: "Код BIC, расположение или название и адрес корреспондента\ + \ получателя. Содержимое поля 54 (за исключением номера счета, с разде\ + лителями) в формате MT103" + example: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW RUSSIAN FEDERATION" + receiverCorrespondentOption: + type: string + description: Признак вида поля корреспондента + example: D + regulatoryReporting: + type: string + description: Контрольная отчетность (формат MT103) + example: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 МS.05.2003/N8/123456789012345/N9/12.05.2003 + remittanceInformation: + type: string + description: "Сведения о переводе (формат MT103, поле 70)" + example: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + senderCharges: + type: string + description: Расходы отправителя (формат MT103) + example: "USD7,03" + senderCorrespondentAccount: + type: string + description: Номер счета корреспондента отправителя. + example: BOTKGB2L + senderCorrespondentName: + type: string + description: "Код BIC, расположение или название и адрес корреспондента\ + \ отправителя. Содержимое поля 53 (за исключением номера счета, с разд\ + елителями) в формате MT103" + example: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentOption: + type: string + description: Признак вида поля корреспондента + example: D + senderToReceiverInformation: + type: string + description: Информация отправителя получателю (формат MT103) + example: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + transactionReferenceNumber: + type: string + description: "Референс операции (формат MT103, поле 20)" + example: "69528" + transactionRelatedReference: + type: string + description: Связанный референс (формат MT103) + transactionTypeCode: + type: string + description: Код типа операции (формат MT103) + example: S01 + urgent: + type: string + description: | + Признак срочности операции (формат MT103) * `URGENT` - Срочная операция * `NORMAL` - Обычная операция + enum: + - URGENT + - NORMAL + valueDateCurrencyInterbankSettledAmount: + type: string + description: "Дата валютирования, код валюты, сумма межбанковского расче\ + та (формат MT103)" + example: "130824EUR5447,34" + description: Блок для описания валютных счетов + example: + bankOperationCode: CRED + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + transactionTypeCode: S01 + instructionCode: instructionCode + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageIdentifier: S000013082900014 + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + beneficiaryCustomerName: ООО Ромашка + instructedAmount: "USD70,00" + transactionRelatedReference: transactionRelatedReference + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + orderingInstitutionAccount: ABOCBNBJ080 + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + intermediaryBankAccount: COBADEFF + transactionReferenceNumber: 69528 + orderingInstitutionOption: D + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW\ + \ RUSSIAN FEDERATION" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + senderCharges: "USD7,03" + receiverCharges: receiverCharges + CurTransfer: + type: object + properties: + bankOperationCode: + type: string + description: Код банковской операции (формат MT103) + enum: + - CRED + beneficiaryBankAccount: + type: string + description: Номер счета банка бенефициара. 1-я часть значения поля 57 в + формате MT103 + example: LOYDGB21323 + beneficiaryBankName: + type: string + description: "Код BIC, расположение или название и адрес банка бенефициа\ + ра. Содержимое поля 57 (за исключением номера счета, с разделителями)\ + \ в формате MT103" + example: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: + type: string + description: Признак вида поля банка бенефициара (поле 57 в формате MT103) + example: D + beneficiaryCustomerAccount: + type: string + description: Номер счета бенефициара. 1-я часть значения поля 59 в формате + MT103 + example: /40702810701300000761 + beneficiaryCustomerName: + type: string + description: "Код BIC/BEI или название и адрес бенефициара. Содержимое п\ + оля 59 (за исключением номера счета, с разделителями) в формате MT103" + example: ООО Ромашка + detailsOfCharges: + type: string + description: | + Сведения о расходах (формат MT103) * `OUR` - Все расходы по данной операции относятся на счет Плательщика + enum: + - OUR + exchangeRate: + type: string + description: Курс конвертации (формат MT103) + example: "67,74" + instructedAmount: + type: string + description: Валюта/сумма по инструкции (формат MT103) + example: "USD70,00" + instructionCode: + type: string + description: Код инструкции (формат MT103) + intermediaryBankAccount: + type: string + description: Номер счета банка-посредника.1-я часть значения поля 56 в формате + MT103 + example: COBADEFF + intermediaryBankName: + type: string + description: "Код BIC или название банка-посредника. Содержимое поля 56\ + \ (за исключением номера счета, с разделителями) в формате MT103" + example: АО "АЛЬФА-БАНК" + intermediaryBankOption: + type: string + description: Признак вида поля банка-посредника + example: D + messageDestinator: + type: string + description: Получатель сообщения SWIFT (формат MT103) + example: LAPBLV2X + messageIdentifier: + type: string + description: Уникальный системный номер сообщения SWIFT (формат MT103) + example: S000013082900014 + messageOriginator: + type: string + description: Отправитель сообщения SWIFT (формат MT103) + example: SABRRU2P + messageReceiveTime: + type: string + description: Дата и время получения сообщения SWIFT (формат MT103) + example: 15-05-27 13:21 + messageSendTime: + type: string + description: Дата и время отправки сообщения SWIFT (формат MT103) + example: 15-05-27 13:21 + messageType: + type: string + description: Тип сообщения SWIFT + enum: + - "103" + orderingCustomerAccount: + type: string + description: Номер счета плательщика в формате + example: /08251801040004813 + orderingCustomerName: + type: string + description: "Код BIC/BEI или название и адрес плательщика.Содержимое по\ + ля 50 (за исключением номера счета, с разделителями) в формате MT103" + example: ООО Радуга + orderingCustomerOption: + type: string + description: Признак вида поля плательщика + example: K + orderingInstitutionAccount: + type: string + description: Номер счета банка плательщика.1-я часть значения поля 52 в + формате MT103 + example: ABOCBNBJ080 + orderingInstitutionName: + type: string + description: "Код BIC или название и адрес банка плательщика. Содержимое\ + \ поля 52 (за исключением номера счета, с разделителями) в формате MT103" + example: АО "АЛЬФА-БАНК" + orderingInstitutionOption: + type: string + description: Признак вида поля банка плательщика + example: D + receiverCharges: + type: string + description: Расходы получателя (формат MT103) + receiverCorrespondentAccount: + type: string + description: Номер счета корреспондента получателя. + example: "30101810400000000000" + receiverCorrespondentName: + type: string + description: "Код BIC, расположение или название и адрес корреспондента\ + \ получателя. Содержимое поля 54 (за исключением номера счета, с разде\ + лителями) в формате MT103" + example: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW RUSSIAN FEDERATION" + receiverCorrespondentOption: + type: string + description: Признак вида поля корреспондента + example: D + regulatoryReporting: + type: string + description: Контрольная отчетность (формат MT103) + example: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 МS.05.2003/N8/123456789012345/N9/12.05.2003 + remittanceInformation: + type: string + description: "Сведения о переводе (формат MT103, поле 70)" + example: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + senderCharges: + type: string + description: Расходы отправителя (формат MT103) + example: "USD7,03" + senderCorrespondentAccount: + type: string + description: Номер счета корреспондента отправителя. + example: BOTKGB2L + senderCorrespondentName: + type: string + description: "Код BIC, расположение или название и адрес корреспондента\ + \ отправителя. Содержимое поля 53 (за исключением номера счета, с разд\ + елителями) в формате MT103" + example: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentOption: + type: string + description: Признак вида поля корреспондента + example: D + senderToReceiverInformation: + type: string + description: Информация отправителя получателю (формат MT103) + example: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + transactionReferenceNumber: + type: string + description: "Референс операции (формат MT103, поле 20)" + example: "69528" + transactionRelatedReference: + type: string + description: Связанный референс (формат MT103) + transactionTypeCode: + type: string + description: Код типа операции (формат MT103) + example: S01 + urgent: + type: string + description: | + Признак срочности операции (формат MT103) * `URGENT` - Срочная операция * `NORMAL` - Обычная операция + enum: + - URGENT + - NORMAL + valueDateCurrencyInterbankSettledAmount: + type: string + description: "Дата валютирования, код валюты, сумма межбанковского расче\ + та (формат MT103)" + example: "130824EUR5447,34" + payeeBankBic: + type: string + description: БИК банка получателя + example: "9611925" + payeeBankCorrAccount: + type: string + description: Корсчёт банка получателя + example: "30101810200000000593" + payeeAccount: + type: string + description: Номер счёта получателя + example: "40802810401300015422" + payeeBankName: + type: string + description: Наименование банка получателя + example: АО \"АЛЬФА-БАНК\" + payeeInn: + type: string + description: ИНН получателя + example: "7728168971" + payeeKpp: + type: string + description: КПП получателя + example: "770801001" + payeeName: + type: string + description: Наименование получателя + example: Наименование получателя + payerAccount: + type: string + description: Номер счёта плательщика + example: "40802810401300015422" + payerBankBic: + type: string + description: БИК банка плательщика + example: "044525593" + payerBankCorrAccount: + type: string + description: Корсчёт банка плательщика + example: "30101810200000000593" + payerBankName: + type: string + description: Наименование банка плательщика + example: АО \"АЛЬФА-БАНК\" + payerInn: + type: string + description: ИНН плательщика + example: "7728168971" + payerKpp: + type: string + description: КПП плательщика + example: "770801001" + payerName: + type: string + description: Наименование плательщика + example: Гаврилов Добрыня Петрович + description: Блок для описания валютных счетов + example: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW\ + \ RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + ResponseSigned: + type: object + properties: + Pagination: + $ref: '#/components/schemas/Pagination' + Statement: + $ref: '#/components/schemas/Statement_1' + ds:Signature: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignature' + description: Ответ для выписки в формате 1С + xml: + name: Response + Pagination: + type: object + properties: + Limit: + minimum: 0 + type: integer + description: Количество записей на одной странице + example: 1000 + xml: + name: Limit + Offset: + minimum: 0 + type: integer + description: "Количество записей в списке, которые были пропущены" + example: 0 + xml: + name: Offset + TotalCount: + minimum: 0 + type: integer + description: Общее количество записей + example: 10000 + xml: + name: TotalCount + description: Данные пагинации + xml: + name: Pagination + Statement_1: + type: object + properties: + creationDate: + type: string + description: Дата и время формирования + example: 2022-01-21T11:25:22.522Z + xml: + name: creationDate + attribute: true + formatVersion: + type: string + description: Версия формата + example: 2.3.2 + xml: + name: formatVersion + attribute: true + id: + type: string + description: Уникальный идентификатор выписки + example: f7cbc6af-33dd-4c37-b67d-7400e1c327ad + xml: + name: id + attribute: true + Data: + $ref: '#/components/schemas/Data' + Recipient: + $ref: '#/components/schemas/Recipient' + Sender: + $ref: '#/components/schemas/Sender' + description: Выписка операций по счетам в формате 1С + xml: + name: Statement + namespace: http://directbank.1c.ru/XMLSchema + Data: + type: object + properties: + Account: + type: string + description: Номер лиц. счета + example: "40702810701300000761" + xml: + name: Account + Bank: + $ref: '#/components/schemas/Bank' + ClosingBalance: + type: number + description: Остаток на счете на конец периода + example: 99407.2 + xml: + name: ClosingBalance + DateFrom: + type: string + description: Начало периода выписки + example: 2021-05-26T00:00:00.000 + xml: + name: DateFrom + DateTo: + type: string + description: Конец периода выписки + example: 2021-05-26T23:59:59.999 + xml: + name: DateTo + OpeningBalance: + type: number + description: Остаток на счете на начало периода + example: 99527.0 + xml: + name: OpeningBalance + OperationInfo: + type: array + description: Информация об одной операции по лицевому счету в выписке + xml: + name: OperationInfo + items: + $ref: '#/components/schemas/OperationInfo' + Stamp: + $ref: '#/components/schemas/Stamp' + StatementType: + type: string + description: | + Тип выписки * `0` - Окончательная выписка + xml: + name: StatementType + enum: + - "0" + - "1" + - "2" + x-enum-varnames: + - ZERO + - ONE + - TWO + TotalCredits: + type: number + description: Общая сумма документов по кредиту счета (поступление) + example: 100000.0 + xml: + name: TotalCredits + TotalDebits: + type: number + description: Общая сумма документов по дебету счета (списание) + example: 853.0 + xml: + name: TotalDebits + description: Данные выписки по лиц. счету + xml: + name: Data + Bank: + type: object + properties: + Bic: + type: string + description: БИК банка + example: "044525593" + xml: + name: BIC + CorrespAcc: + type: string + description: Коррсчет банка + example: "30101810200000000593" + xml: + name: CorrespAcc + Name: + type: string + description: Название банка + example: АО "АЛЬФА-БАНК" + xml: + name: Name + description: Данные банка + OperationInfo: + type: object + properties: + Date: + type: string + description: Дата проводки документа по лиц. счету + example: 2022-01-20 + xml: + name: Date + Dc: + $ref: '#/components/schemas/Dc' + ExtId: + type: string + description: ID исходного платежного документа плательщик + example: "null" + xml: + name: ExtID + PayDoc: + $ref: '#/components/schemas/PayDoc' + Stamp: + $ref: '#/components/schemas/PayDocStamp' + description: Информация об одной операции по лицевому счету в выписке + Dc: + type: string + description: | + Признак дебета/кредита * `1` - Операция по дебету (списание со счета) * `2` - Операция по кредиту (поступление на счет) + xml: + name: DC + enum: + - "1" + - "2" + x-enum-varnames: + - DEBIT + - CREDIT + PayDoc: + type: object + properties: + PayDocRu: + $ref: '#/components/schemas/PayDocRu' + PayRequest: + $ref: '#/components/schemas/PayRequest' + CollectionOrder: + $ref: '#/components/schemas/PayDocRu' + PaymentOrder: + $ref: '#/components/schemas/PaymentOrder' + BankOrder: + $ref: '#/components/schemas/BankOrder' + MemOrder: + $ref: '#/components/schemas/BankOrder' + docKind: + type: string + description: | + Код вида электронного документа * `10` - Платежное поручение * `11` - Платежное требование * `16` - Мемориальный ордер * `17` - Платежный ордер * `18` - Банковский ордер + xml: + name: docKind + attribute: true + enum: + - "10" + - "10" + - "11" + - "16" + - "17" + - "18" + - "18" + x-enum-varnames: + - PAYMENT + - PAYMENT_ORDER + - PAYMENT_REQUEST + - MEMORY_ORDER + - COLLECTION_LETTER + - BANK_ORDER + - DEFAULT + id: + type: string + description: Идентификатор платежного документа в банке + example: 1220120MOPYTMD0000031_artificially_created + xml: + name: id + attribute: true + extId: + type: string + xml: + name: extId + attribute: true + PayDocRu: + type: object + properties: + BudgetPaymentInfo: + $ref: '#/components/schemas/BudgetPaymentInfo' + Code: + type: string + description: Уникальный идентификатор платежа (поле 22) + example: "0" + xml: + name: Code + DocDate: + type: string + description: Дата составления (поле 4) + example: 2019-05-04 + xml: + name: DocDate + DocNo: + type: string + description: Номер документа (поле 3) + example: "768" + xml: + name: DocNo + IncomeTypeCode: + type: string + description: Код вида дохода (поле 20) + example: "2" + xml: + name: IncomeTypeCode + Payee: + $ref: '#/components/schemas/Accounts' + Payer: + $ref: '#/components/schemas/Accounts' + PaymentKind: + $ref: '#/components/schemas/PaymentKind' + Priority: + type: string + description: Очередность платежа (поле 21) + example: "5" + xml: + name: Priority + Purpose: + type: string + description: Назначение платежа (поле 24) + example: Комиссия за переводы в валюте РФ за 2022-01-20. + xml: + name: Purpose + Sum: + type: number + description: Сумма документа (поле 7) + example: 36.0 + xml: + name: Sum + TransitionKind: + type: string + description: Вид операции (поле 18) + example: "17" + xml: + name: TransitionKind + description: Данные платежного поручения + xml: + name: PayDocRu + BudgetPaymentInfo: + type: object + properties: + Cbc: + type: string + description: Код бюджетной классификации (КБК) в соответствии с классификацией + доходов бюджетов РФ (поле 104) + example: "0" + xml: + name: CBC + DocDate: + type: string + description: Дата налогового документа или 0 (поле 109) + example: 22.01.2022 + xml: + name: DocDate + DocNo: + type: string + description: Номер налогового документа (поле 108) + example: "12345" + xml: + name: DocNo + DrawerStatus: + type: string + description: Статус составителя (поле 101). + example: "1" + xml: + name: DrawerStatus + Oktmo: + type: string + description: Значение кода ОКТМО муниципального образования (поле 105) + example: "54701000" + xml: + name: OKTMO + PayType: + type: string + description: Код выплат (поле 110) + example: "1" + xml: + name: PayType + Reason: + type: string + description: Основание налогового платежа (поле 106) + example: ТП + xml: + name: Reason + TaxPeriod: + type: string + description: Налоговый период / код таможенного органа (поле 107) + example: МС.03.2016 + xml: + name: TaxPeriod + Accounts: + type: object + properties: + Account: + type: string + description: Расчетный счет клиента + example: "40702810701300000761" + xml: + name: Account + Bank: + $ref: '#/components/schemas/Bank' + Inn: + type: string + description: ИНН налогоплательщика + example: "25247358" + xml: + name: INN + Kpp: + type: string + description: КПП налогоплательщика + example: "037186025" + xml: + name: KPP + Name: + type: string + description: Наименование налогоплательщика + example: Полное наименование Орг № 11329 + xml: + name: Name + description: Данные налогоплательщика + PaymentKind: + type: string + description: Вид платежа (поле 5) + xml: + name: PaymentKind + enum: + - электронно + - телеграфом + - почтой + - срочно + x-enum-varnames: + - ELECTRONICALLY + - TELEGRAPH + - POST + - URGENT + PayRequest: + type: object + properties: + AcceptTerm: + type: integer + description: Срок для акцепта (поле 36) + format: int32 + example: 0 + xml: + name: AcceptTerm + Code: + type: string + description: Уникальный идентификатор платежа (поле 22) + example: "0" + xml: + name: Code + DocDate: + type: string + description: Дата составления (поле 4) + example: 2019-05-04 + xml: + name: DocDate + DocDispatchDate: + type: string + description: Дата отсылки (вручения) плательщику предусмотренных договором + документов (поле 37) + example: 20.01.2022 + xml: + name: DocDispatchDate + DocNo: + type: string + description: Номер документа (поле 3) + example: "768" + xml: + name: DocNo + IncomeTypeCode: + type: string + description: Код вида дохода (поле 20) + example: "2" + xml: + name: IncomeTypeCode + Payee: + $ref: '#/components/schemas/Accounts' + Payer: + $ref: '#/components/schemas/Accounts' + PaymentCondition: + type: string + description: Условие оплаты (поле 35) + example: "1" + xml: + name: PaymentCondition + PaymentKind: + $ref: '#/components/schemas/PaymentKind' + Priority: + type: string + description: Очередность платежа (поле 21) + example: "5" + xml: + name: Priority + Purpose: + type: string + description: Назначение платежа (поле 24) + example: Комиссия за переводы в валюте РФ за 2022-01-20. + xml: + name: Purpose + Sum: + type: number + description: Сумма документа (поле 7) + example: 36.0 + xml: + name: Sum + TransitionKind: + type: string + description: Вид операции (поле 18) + example: "17" + xml: + name: TransitionKind + description: Данные платежного требования + xml: + name: PayRequest + PaymentOrder: + type: object + properties: + BudgetPaymentInfo: + $ref: '#/components/schemas/BudgetPaymentInfo' + Code: + type: string + description: Уникальный идентификатор платежа (поле 22) + example: "0" + xml: + name: Code + DocDate: + type: string + description: Дата составления (поле 4) + example: 2019-05-04 + xml: + name: DocDate + DocNo: + type: string + description: Номер документа (поле 3) + example: "768" + xml: + name: DocNo + IncomeTypeCode: + type: string + description: Код вида дохода (поле 20) + example: "2" + xml: + name: IncomeTypeCode + PartialDocDate: + type: string + description: Дата платежного документа (поле 41) + example: 20.01.2022 + xml: + name: PartialDocDate + PartialDocNo: + type: string + description: Номер платежного документа (поле 40) + example: "12345" + xml: + name: PartialDocNo + PartialPaymentNo: + type: string + description: Номер частичного платежа (поле 38) + example: "0" + xml: + name: PartialPaymentNo + PartialTransitionKind: + type: string + description: Шифр платежного документа (поле 39) + example: "3" + xml: + name: PartialTransitionKind + Payee: + $ref: '#/components/schemas/Accounts' + Payer: + $ref: '#/components/schemas/Accounts' + PaymentKind: + $ref: '#/components/schemas/PaymentKind' + Priority: + type: string + description: Очередность платежа (поле 21) + example: "5" + xml: + name: Priority + Purpose: + type: string + description: Назначение платежа (поле 24) + example: Комиссия за переводы в валюте РФ за 2022-01-20. + xml: + name: Purpose + Sum: + type: number + description: Сумма документа (поле 7) + example: 36.0 + xml: + name: Sum + SumResidualPayment: + type: number + description: Сумма остатка платежа (поле 42) + example: 0 + xml: + name: SumResidualPayment + TransitionContent: + type: string + description: Содержание операции (поле 70) + example: "null" + xml: + name: TransitionContent + TransitionKind: + type: string + description: Вид операции (поле 18) + example: "17" + xml: + name: TransitionKind + description: Данные платежного ордера + xml: + name: PaymentOrder + BankOrder: + type: object + properties: + Code: + type: string + description: Уникальный идентификатор платежа (поле 22) + example: "0" + xml: + name: Code + DocDate: + type: string + description: Дата составления (поле 4). + example: 2022-01-22 + xml: + name: DocDate + DocNo: + type: string + description: Номер документа (поле 3). + example: "12345" + xml: + name: DocNo + Payee: + $ref: '#/components/schemas/Accounts' + Payer: + $ref: '#/components/schemas/Accounts' + PaymentKind: + $ref: '#/components/schemas/PaymentKind' + Priority: + type: string + description: Очередность платежа (поле 21) + example: "5" + xml: + name: Priority + Purpose: + type: string + description: Назначение платежа (поле 24) + example: За транспортные услуги + xml: + name: Purpose + Sum: + type: number + description: Сумма документа (поле 7). + example: 14 + xml: + name: Sum + TransitionKind: + type: string + description: Вид операции (поле 18) + example: "17" + xml: + name: TransitionKind + description: Данные банковского ордера + PayDocStamp: + type: object + properties: + Bic: + type: string + description: БИК банка + example: "044525593" + xml: + name: BIC + Branch: + type: string + description: Отделение банка + xml: + name: Branch + CorrespAcc: + type: string + description: Коррсчет банка + example: "30101810200000000593" + xml: + name: CoreespAcc + Name: + type: string + description: Название банка + example: АО \"АЛЬФА-БАНК\" + xml: + name: Name + Status: + $ref: '#/components/schemas/PayDocStampStatus' + description: Данные штампа банка по каждому платежному документу + PayDocStampStatus: + type: object + properties: + Code: + type: string + description: Код статуса (02 - Исполнен) + example: "2" + xml: + name: Code + Name: + type: string + description: Наименование статуса на стороне банка + example: Исполнен + xml: + name: Name + MoreInfo: + type: string + description: Дополнительная информация к статусу + example: "null" + xml: + name: MoreInfo + description: Статус платежного документа в банке + Stamp: + type: object + properties: + Bic: + type: string + description: БИК банка + example: "044525593" + xml: + name: BIC + CorrespAcc: + type: string + description: Коррсчет банка + example: "30101810200000000593" + xml: + name: CorrespAcc + ExtIdStatementRequest: + type: string + description: "ID исходного запроса на выписку, если такой был" + example: "null" + xml: + name: ExtIDStatementRequest + Name: + type: string + description: Название банка + example: АО \"АЛЬФА-БАНК\" + xml: + name: Name + description: Данные штампа банка по выписке в целом + xml: + name: Stamp + Recipient: + type: object + properties: + id: + type: string + description: "Идентификатор клиента, как он задан на стороне банка" + example: "40702810701300000761" + xml: + name: id + attribute: true + inn: + type: string + description: ИНН клиента + example: "25247358" + xml: + name: inn + attribute: true + kpp: + type: string + description: КПП клиента + example: "037186025" + xml: + name: kpp + attribute: true + name: + type: string + description: Название клиента + example: Полное наименование Орг № 11329 + xml: + name: name + attribute: true + description: Получаетель + Sender: + type: object + properties: + bic: + type: string + description: БИК банка + example: "044525593" + xml: + name: bic + attribute: true + name: + type: string + description: Название банка + example: АО "АЛЬФА-БАНК" + xml: + name: name + attribute: true + description: Отправитель + ResponseSignatureRsaXmlSignature: + type: object + properties: + ds:SignedInfo: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo' + ds:SignatureValue: + type: string + description: Значение подписи + example: | + MRrLr4sMR0ADi12A3PSLPVP+Y8yxTml3TyMMlTl2K9EhyyFrqQPnxHJfQALLC129n+oFSNFdXr0X + 3kHEMnBU8mqGPSWPVMHqb1iE+ZyhNXZYQQIyveS43KZAp8USr83tg9CtEUxy6FjYFsYJZgGIirG+ + fj9S7PFqn95Bl0fkIZp636s3J1CHr1d9AJBpyJuF8G8TNTPJK1w9po1ObX8iMgtrOG44Vkk3Spp+ + kEvEFGflD3pOL/vkaiOOwHqmwBHHc24prczAXg7zsYvHlSdUhHABgx9XFz8tJlg3dNtTQVaHti7X + pUAyAGjBsXOXbjbIRz3lBS59N2LIffB0GsMalQ== + Id: + type: string + example: sigID1 + xml: + attribute: true + ds:KeyInfo: + $ref: '#/components/schemas/ResponseSignatureRsaXmlKeyInfo' + description: Ответ XMLDsig + xml: + name: ds:Signature + namespace: http://www.w3.org/2000/09/xmldsig# + ResponseSignatureRsaXmlSignedInfo: + type: object + properties: + ds:CanonicalizationMethod: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_CanonicalizationMethod' + ds:SignatureMethod: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_SignatureMethod' + ds:Reference: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_Reference' + ResponseSignatureRsaXmlTransform1: + type: object + allOf: + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransformParams' + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransform1_allOf' + ResponseSignatureRsaXmlTransformParams: + required: + - Algorithm + type: string + discriminator: + propertyName: Algorithm + ResponseSignatureRsaXmlTransform2: + type: object + allOf: + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransformParams' + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransform2_allOf' + ResponseSignatureRsaXmlKeyInfo: + type: object + properties: + ds:X509Data: + $ref: '#/components/schemas/ResponseSignatureRsaXmlKeyInfo_ds_X509Data' + ErrorBadRequestXML: + type: object + properties: + Error: + type: string + description: Код ошибки + example: invalid_request + xml: + name: Error + ErrorDescription: + type: string + description: Сообщение об ошибке + example: Authorization header is not present in request headers + xml: + name: ErrorDescription + description: Ошибка запроса + xml: + name: ErrorResponse + ErrorUnauthorizedXML: + type: object + properties: + Error: + type: string + description: Код ошибки + example: invalid_token + xml: + name: Error + ErrorDescription: + type: string + description: Сообщение об ошибке + example: "The access token provided is expired, revoked, malformed, or invalid\ + \ for other reasons" + xml: + name: ErrorDescription + description: Ошибка авторизации + xml: + name: ErrorResponse + ErrorScopeXML: + type: object + properties: + Error: + type: string + description: Код ошибки + example: insufficient_scope + xml: + name: Error + ErrorDescription: + type: string + description: Сообщение об ошибке + example: The request requires higher privileges than provided by the access + token + xml: + name: ErrorDescription + description: Ошибка прав доступа + xml: + name: ErrorResponse + ErrorNotFoundXML: + type: object + properties: + Error: + type: string + description: Код ошибки + example: unknown_endpoint + xml: + name: Error + ErrorDescription: + type: string + description: Сообщение об ошибке + example: Endpoint is not found or not active + xml: + name: ErrorDescription + description: Ошибка прав доступа + xml: + name: ErrorResponse + ErrorInternalXML: + type: object + properties: + Error: + type: string + description: Код ошибки + example: internal_error + xml: + name: Error + ErrorDescription: + type: string + description: Сообщение об ошибке + example: Internal server error + xml: + name: ErrorDescription + description: Ошибка сервера + xml: + name: ErrorResponse + StatementMT940: + type: string + description: 20 - Референс операции; 25 - Номер счета; 28С - Номер выписки; + 60а - Входящий остаток; 61 - Строка движения по счету; 86 - Информация для + владельца счета; 62а - Исходящий остаток + example: |- + :20:+57610880b621435 + :25:40702810701300000761 + :28C:1 + :60a:C220112RUR99527,00 + :61:220113DR20,00NTRFNONREF + 20/00000/50012008 + :86:/BENM//03271643540000095400 INN5752006960.KPP575301001 GAVRILOV DOBRYNa TROFIMOVIc /NZP/'(VO21100)' OPLATA PO DOGOVORU + :62a:C220113RUR99407,00 + ErrorBadRequestText: + type: string + description: Ошибка запроса + example: |- + error: invalid_request + error_description: Authorization header is not present in request headers + ErrorUnauthorizedText: + type: string + description: Ошибка авторизации + example: |- + error: invalid_token + error_description: The access token provided is expired, revoked, malformed, or invalid for other reasons + ErrorScopeText: + type: string + description: Ошибка прав доступа + example: |- + error: insufficient_scope + error_description: The request requires higher privileges than provided by the access token + ErrorNotFoundText: + type: string + example: |- + error: unknown_endpoint + error_description: Endpoint is not found or not active + ErrorInternalText: + type: string + description: Ошибка сервера + example: |- + error: internal_error + error_description: Internal server error + StatementSummary: + type: object + properties: + composedDateTime: + type: string + description: Дата составления сводки + example: 2018-12-31 + lastMovementDate: + type: string + description: Дата последней операции по счёту за запрошенный период + example: 2018-12-31 + openingRate: + type: string + description: Курс ЦБ за единицу валюты на начало периода + openingBalance: + $ref: '#/components/schemas/OpeningBalance' + openingBalanceRub: + $ref: '#/components/schemas/OpeningBalanceRub' + closingBalance: + $ref: '#/components/schemas/ClosingBalance' + closingBalanceRub: + $ref: '#/components/schemas/ClosingBalanceRub' + debitTurnover: + $ref: '#/components/schemas/DebitTurnover' + debitTurnoverRub: + $ref: '#/components/schemas/DebitTurnoverRub' + debitTransactionsNumber: + type: integer + description: Количество дебетовых операций по счёту + example: 10 + creditTurnover: + $ref: '#/components/schemas/CreditTurnover' + creditTurnoverRub: + $ref: '#/components/schemas/CreditTurnoverRub' + creditTransactionsNumber: + type: integer + description: Количество кредитовых операций по счёту + example: 10 + description: Информация об оборотах + example: + debitTurnover: + amount: 10000.0 + currencyName: RUR + openingBalanceRub: + amount: 10000.55 + currencyName: RUR + closingBalance: + amount: 25000.3 + currencyName: RUR + creditTurnoverRub: + amount: 24999.75 + currencyName: RUR + debitTransactionsNumber: 10 + composedDateTime: 2018-12-31 + creditTurnover: + amount: 24999.75 + currencyName: RUR + openingRate: openingRate + debitTurnoverRub: + amount: 10000.0 + currencyName: RUR + openingBalance: + amount: 10000.55 + currencyName: RUR + closingBalanceRub: + amount: 25000.3 + currencyName: RUR + creditTransactionsNumber: 10 + lastMovementDate: 2018-12-31 + OpeningBalance: + type: object + properties: + amount: + type: number + description: Сумма + example: 10000.55 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Входящий остаток в валюте счёта + example: + amount: 10000.55 + currencyName: RUR + OpeningBalanceRub: + type: object + properties: + amount: + type: number + description: Сумма + example: 10000.55 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Входящий остаток в рублях + example: + amount: 10000.55 + currencyName: RUR + ClosingBalance: + type: object + properties: + amount: + type: number + description: Сумма + example: 25000.3 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Исходящий остаток в валюте счёта + example: + amount: 25000.3 + currencyName: RUR + ClosingBalanceRub: + type: object + properties: + amount: + type: number + description: Сумма + example: 25000.3 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Исходящий остаток в рублях + example: + amount: 25000.3 + currencyName: RUR + DebitTurnover: + type: object + properties: + amount: + type: number + description: Сумма + example: 10000.0 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Дебетовый оборот в валюте счёта + example: + amount: 10000.0 + currencyName: RUR + DebitTurnoverRub: + type: object + properties: + amount: + type: number + description: Сумма + example: 10000.0 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Дебетовый оборот в рублях + example: + amount: 10000.0 + currencyName: RUR + CreditTurnover: + type: object + properties: + amount: + type: number + description: Сумма + example: 24999.75 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Кредитовый оборот в валюте счёта + example: + amount: 24999.75 + currencyName: RUR + CreditTurnoverRub: + type: object + properties: + amount: + type: number + description: Сумма + example: 24999.75 + currencyName: + type: string + description: Буквенный ISO-код валюты + example: RUR + description: Кредитовый оборот в рублях + example: + amount: 24999.75 + currencyName: RUR + CorrespondentStatement: + type: object + properties: + pagination: + $ref: '#/components/schemas/SimplePage' + items: + type: array + description: Массив транзакций + items: + $ref: '#/components/schemas/TransactionsCorrespondent_inner' + description: Выписка операций по корреспондентским счетам + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + items: + - documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + - documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK\ + \ MOSCOW RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + TransactionsCorrespondent: + type: array + description: Массив транзакций + items: + $ref: '#/components/schemas/TransactionsCorrespondent_inner' + RequestsCreateFileTransaction: + type: object + properties: + requestId: + type: string + description: Идентификатор запроса + example: 67e50b09-a203-4119-86cb-647d06a803a0 + executeDate: + type: string + description: Дата исполнения + example: 2022-01-13 + format: + type: string + description: Формат выписки + enum: + - pdf + - xls + - csv + - 1c + withDocument: + type: boolean + description: "Параметр, добавляющий к выписке все документы по транзакиц\ + ям. Доступно только для формата PDF" + withSignature: + type: boolean + description: Параметр необходимости скачивания документа с подписью. Доступно + только для формата PDF + description: Данные запроса + example: + executeDate: 2022-01-13 + requestId: 67e50b09-a203-4119-86cb-647d06a803a0 + format: pdf + withSignature: true + withDocument: true + ResponseGetFileTransaction: + type: object + properties: + requestId: + type: string + description: Идентификатор запроса + example: 67e50b09-a203-4119-86cb-647d06a803a0 + status: + type: string + description: Статус + enum: + - SUCCEED + - PROCESSING + - ERROR + downloadFileLinks: + type: array + description: Данные ответа + items: + $ref: '#/components/schemas/DownloadFileLinks_inner' + description: Данные ответа + example: + downloadFileLinks: + - method: GET + url: https://baas.alfabank.ru/filebox/secure-file-transfer.outgoing-files.to-processing/f190bfef-aad6-ce9b-9224-f11ef60564cb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 + - method: GET + url: https://baas.alfabank.ru/filebox/secure-file-transfer.outgoing-files.to-processing/f190bfef-aad6-ce9b-9224-f11ef60564cb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 + requestId: 67e50b09-a203-4119-86cb-647d06a803a0 + status: SUCCEED + DownloadFileLinks: + type: array + description: Данные ответа + items: + $ref: '#/components/schemas/DownloadFileLinks_inner' + AccountResponse: + maxProperties: 3 + minProperties: 3 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/AccountResponse_Data' + Links: + $ref: '#/components/schemas/AccountResponse_Links' + Meta: + $ref: '#/components/schemas/AccountResponse_Meta' + additionalProperties: false + description: Список счетов и их идентификаторы + example: + Meta: null + Links: + self: https://sb.example.ru/v1.3/example + Data: null + DataAccountResponse: + type: object + properties: + Account: + maxItems: 50 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/Account_1' + additionalProperties: false + description: Полезная нагрузка ответа на запрос о списке счетов + Account_1: + required: + - accountDescription + - accountId + - accountType + - currency + - status + type: object + properties: + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса" + example: this-is-a-slug-format-account-id + status: + description: Статус счета в форме кода + allOf: + - $ref: '#/components/schemas/AccountStatus' + statusUpdateDateTime: + description: Дата и время изменения статуса счета + allOf: + - $ref: '#/components/schemas/ISODateTime' + currency: + description: Валюта ведения счета + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + accountType: + description: Тип счета (физическое или юридическое лицо) + allOf: + - $ref: '#/components/schemas/AccountType' + accountDescription: + maxLength: 128 + minLength: 1 + pattern: "^[\\w\\W]{1,128}$" + type: string + description: "Краткое описание назначения счета или продукта, привязанно\ + го к счету" + example: Розничные операции + AccountDetails: + maxItems: 24 + minItems: 1 + type: array + description: Идентификация счета + items: + $ref: '#/components/schemas/CashAccount' + Owner: + $ref: '#/components/schemas/Account_1_Owner' + Servicer: + $ref: '#/components/schemas/Account_1_Servicer' + additionalProperties: false + description: Счет + x-openapiru-object-type-contract: true + AccountStatus: + type: string + description: Статус счета + example: Enabled + enum: + - Enabled + - Disabled + - Deleted + x-enum-descriptions: + - Cчет доступен и может использоваться + - "Cчет не доступен и не может использоваться, временно или навсегда" + - Счет удален и не может использоваться + x-enum-varnames: + - Enabled + - Disabled + - Deleted + ISODateTime: + type: string + description: Формат даты и времени + format: date-time + example: 2021-06-05T15:15:13Z + ActiveOrHistoricCurrencyCode: + pattern: "^[A-Z]{3,3}$" + type: string + description: "Код валюты, соответствующий международному стандарту ISO 4217" + example: RUB + AccountType: + type: string + description: Тип счета + enum: + - Business + - Personal + x-enum-descriptions: + - Счет юридического лица + - Счет физического лица + x-enum-varnames: + - Business + - Personal + CashAccount: + required: + - identification + - schemeName + type: object + properties: + name: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: "Наименование счета, присвоенное учреждением, обслуживающим\ + \ счет, по согласованию с владельцем счета для обеспечения дополнител\ + ьных средств идентификации счета" + example: Основной счет + schemeName: + description: Наименование схемы идентификации счета + allOf: + - $ref: '#/components/schemas/AccountIdentificationCode' + identification: + maxLength: 256 + minLength: 1 + pattern: "^[\\w\\W]{1,256}$" + type: string + description: "Идентификатор счета, соответствующий схеме идентификации,\ + \ известный владельцу счета (номер банковского счета, номер карты, ном\ + ер телефона ...)" + example: "40817810621234570000" + additionalProperties: false + description: Идентификация счета + AccountIdentificationCode: + type: string + description: Схема идентификации счета + example: RU.CBR.BBAN + enum: + - RU.CBR.BBAN + - RU.CBR.EPID + - RU.CBR.PAN + - RU.CBR.MTEL + - RU.CBR.ORID + x-enum-descriptions: + - Базовый номер банковского счета (RUCBRAccountIdentifier) + - Идентификатор электронного средства платежа + - Идентификатор счета по номеру карты + - Идентификатор счета по номеру телефона + - "Иной идентификатор (номер, однозначно идентифицирующий счет стороны)" + x-enum-varnames: + - BBAN + - EPID + - PAN + - MTEL + - ORID + PartyIdentification: + required: + - Identification + - name + type: object + properties: + name: + maxLength: 160 + minLength: 1 + pattern: "^[\\w\\W]{1,160}$" + type: string + description: Наименование организации или имя физического лица + example: Наименование организации или физического лица + mobileNumber: + pattern: "^((\\+7|7|8)([0-9]){10})$" + type: string + description: Номер мобильного телефона + example: "79206001010" + countryOfResidence: + description: Страна проживания + allOf: + - $ref: '#/components/schemas/CountryCode' + countryOfBirth: + description: Место рождения (страна) + allOf: + - $ref: '#/components/schemas/CountryCode' + provinceOfBirth: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Место рождения (область). + example: Ставропольский край + cityOfBirth: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Место рождения (город) + example: Ставрополь + birthDate: + description: Дата рождения + allOf: + - $ref: '#/components/schemas/ISODateTime' + Identification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация юридического или физического лица. + items: + $ref: '#/components/schemas/IdentificationType' + PostalAddress: + $ref: '#/components/schemas/PostalAddress' + additionalProperties: false + description: "Информация об участнике, используемая для идентификации юридич\ + еского или физического лица" + CountryCode: + pattern: "^[A-Z]{2,2}$" + type: string + description: Код страны в формате ISO 3166-1 alpha-2 + example: RU + IdentificationType: + required: + - identification + - schemeName + type: object + properties: + schemeName: + description: Наименование идентификационной схемы юридического или физического + лица + allOf: + - $ref: '#/components/schemas/PartyIdentificationCode' + identification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Уникальный и однозначный идентификатор участника, присвоен\ + ный идентифицирующей организацией." + example: "7728240240" + additionalProperties: false + description: Идентификация физического лица + PartyIdentificationCode: + maxLength: 35 + type: string + description: Схема идентификации юридического или физического лица + example: RU.CBR.TXID + enum: + - RU.CBR.TXID + - RU.CBR.LEI + - RU.CBR.PASP + - RU.CBR.CLID + - RU.CBR.QRST + - RU.CBR.TAXT + - RU.CBR.OGRN + - RU.CBR.SNILS + - RU.CBR.PAN + - RU.CBR.MTEL + - RU.CBR.BBAN + x-enum-descriptions: + - Используется в случае идентификационной схемы ИНН/КИО + - Код организации в соответствии с ISO 17442 + - Номер паспорта + - Другой идентификатор + - Идентификатор в виде QR - кода + - КПП + - ОГРН + - СНИЛС + - Идентификатор платежной карты + - Номер мобильного телефона + - Идентификатор банковского счета + x-enum-varnames: + - TXID + - LEI + - PASP + - CLID + - QRST + - TAXT + - OGRN + - SNILS + - PAN + - MTEL + - BBAN + PostalAddress: + type: object + properties: + addressType: + description: Тип адреса + example: Postal + allOf: + - $ref: '#/components/schemas/AddressTypeCode' + addressLine: + maxItems: 2 + minItems: 0 + type: array + description: Строка адреса + example: + - Адрес в виде строки + - вторая часть строки адреса + items: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: Строка адреса + streetName: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: Наименование улицы или проспекта + example: Садовая + buildingNumber: + maxLength: 16 + minLength: 1 + pattern: "^[\\w\\W]{1,16}$" + type: string + description: "Номер, который определяет положение здания на улице" + example: "11" + postCode: + maxLength: 16 + minLength: 6 + pattern: "^[\\w\\W]{6,16}$" + type: string + description: Почтовый индекс + example: "0100010" + townName: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Наименование населённого пункта или территории, находящейс\ + я вне границ поселений" + example: Бигсити + countrySubDivision: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Наименование и тип субъекта Российской Федерации + example: Мой край + country: + description: Название страны в кодированной форме + allOf: + - $ref: '#/components/schemas/CountryCode' + additionalProperties: false + description: Почтовый адрес + AddressTypeCode: + type: string + description: Тип адреса + example: Postal + enum: + - Business + - Correspondence + - DeliveryTo + - MailTo + - POBox + - Postal + - Residential + - Statement + x-enum-descriptions: + - "Адрес, указанный в едином государственном реестре юридических лиц" + - Адрес для корреспонденции + - Адрес доставки + - Почтовый ящик + - Абонентский ящик + - Фактический/почтовый адрес местонахождения юридического лица + - Адрес постоянной регистрации физического лица (прописка) + - Адрес временной регистрации физического лица (регистрация временного пребывания) + x-enum-varnames: + - Business + - Correspondence + - DeliveryTo + - MailTo + - POBox + - Postal + - Residential + - Statement + BranchAndFinancialInstitutionInformationPilot: + required: + - BankIdentification + - CorrespondentAccount + - OrganizationIdentification + - PostalAddress + - name + type: object + properties: + name: + maxLength: 160 + minLength: 1 + pattern: "^[\\w\\W]{1,160}$" + type: string + description: Наименование организации + example: Наименование организации или физического лица + BankIdentification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация финансового учреждения + items: + $ref: '#/components/schemas/BranchAndFinancialInstitutionIdentification' + OrganizationIdentification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация юридического лица. + items: + $ref: '#/components/schemas/IdentificationType' + CorrespondentAccount: + $ref: '#/components/schemas/BranchAndFinancialInstitutionInformationPilot_CorrespondentAccount' + PostalAddress: + $ref: '#/components/schemas/BranchAndFinancialInstitutionInformationPilot_PostalAddress' + additionalProperties: false + description: Информация о кредитной организации + BranchAndFinancialInstitutionIdentification: + required: + - identification + - schemeName + type: object + properties: + schemeName: + description: Наименование идентификационной схемы финансового учреждения + allOf: + - $ref: '#/components/schemas/FinancialInstitutionIdentificationCode' + identification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Банковский идентификационный код (БИК) или другой идентификатор + финансового учреждения + example: "9612123" + additionalProperties: false + description: Идентификация финансового учреждения + FinancialInstitutionIdentificationCode: + type: string + description: Схема идентификации финансового учреждения + example: RU.CBR.BIC + enum: + - RU.CBR.BICFI + - RU.CBR.BIC + x-enum-descriptions: + - BIC для финансовых учреждений согласно ISO 9362 + - "Уникальный идентификатор банка, используемый в платежных документах на те\ + рритории Российской Федерации" + x-enum-varnames: + - BICFI + - BIC + BranchAndFinancialInstitutionInformation: + required: + - BankIdentification + - name + type: object + properties: + name: + maxLength: 160 + minLength: 1 + pattern: "^[\\w\\W]{1,160}$" + type: string + description: Наименование организации + example: Наименование организации или физического лица + BankIdentification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация финансового учреждения + items: + $ref: '#/components/schemas/BranchAndFinancialInstitutionIdentification' + OrganizationIdentification: + maxItems: 12 + minItems: 0 + type: array + description: Идентификация юридического лица. + items: + $ref: '#/components/schemas/OrganizationIdentificationType' + CorrespondentAccount: + $ref: '#/components/schemas/BranchAndFinancialInstitutionInformationPilot_CorrespondentAccount' + PostalAddress: + $ref: '#/components/schemas/PostalAddress' + additionalProperties: false + description: Информация о кредитной организации + OrganizationIdentificationType: + required: + - identification + - schemeName + type: object + properties: + schemeName: + description: Наименование идентификационной схемы юридического или физического + лица + allOf: + - $ref: '#/components/schemas/OrganizationIdentificationCode' + identification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Уникальный и однозначный идентификатор участника, присвоен\ + ный идентифицирующей организацией." + example: "7728240240" + additionalProperties: false + description: Идентификация юридического лица + OrganizationIdentificationCode: + maxLength: 35 + type: string + description: Схема идентификации юридического лица + example: RU.CBR.TXID + enum: + - RU.CBR.TXID + - RU.CBR.LEI + - RU.CBR.TAXT + - RU.CBR.OGRN + - RU.CBR.OKPO + x-enum-descriptions: + - Используется в случае идентификационной схемы ИНН/КИО + - Код организации в соответствии с ISO 17442 + - КПП + - ОГРН + - ОКПО + x-enum-varnames: + - TXID + - LEI + - TAXT + - OGRN + - OKPO + Links_1: + required: + - self + type: object + properties: + self: + type: string + description: Текущая ссылка + format: uri + example: https://sb.example.ru/v1.3/example?page=1 + first: + type: string + description: Первая ссылка + format: uri + example: https://sb.example.ru/v1.3/example?page=1 + prev: + type: string + description: Предыдущая ссылка + format: uri + example: https://sb.example.ru/v1.3/example?page=1 + next: + type: string + description: Следующая ссылка + format: uri + example: https://sb.example.ru/v1.3/example?page=1 + last: + type: string + description: Последняя ссылка + format: uri + example: https://sb.example.ru/v1.3/example?page=1 + additionalProperties: false + description: "Поставщик услуг предоставляет постраничный ответ для операций\ + \ GET, которые возвращают множественные записи." + example: + next: https://sb.example.ru/v1.3/example?page=1 + last: https://sb.example.ru/v1.3/example?page=1 + prev: https://sb.example.ru/v1.3/example?page=1 + self: https://sb.example.ru/v1.3/example?page=1 + first: https://sb.example.ru/v1.3/example?page=1 + Meta: + type: object + properties: + totalPages: + maximum: 5000 + minimum: 1 + type: integer + description: Указывает на количество передаваемых страниц + format: int32 + example: 1 + additionalProperties: false + description: "Дополнительные данные о запросе. «totalPages», указывает на ко\ + личество передаваемых страниц. Если передается более одной страницы, то эл\ + емент «totalPages» обязательно присутствует." + OBRUErrorResponse: + required: + - Errors + - code + - message + type: object + properties: + code: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Высокоуровневый текстовый код ошибки, необходимый для клас\ + сификации" + example: "400" + id: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный идентификатор ошибки, для целей аудита, в случа\ + е неизвестных / не классифицированных ошибок" + example: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: "Краткое сообщение об ошибке. Например, «что-то не так с пр\ + едоставленными параметрами запроса»" + example: Bad Request + Errors: + maxItems: 50 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/OBRUError' + additionalProperties: false + description: Контейнер с детализацией ошибки + OBRUError: + required: + - errorCode + - message + type: object + properties: + errorCode: + $ref: '#/components/schemas/OBRUErrorResponseErrorCode' + message: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: Описание ошибки + example: Обязательное поле не указано + path: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: "Путь к элементу с ошибкой в JSON объекте. Рекомендуемое, н\ + о не обязательное поле" + example: Data.Model.Object.name + url: + type: string + description: "URL для помощи в устранении проблемы, Также через URL можн\ + о предоставлять дополнительную информацию" + format: uri + example: https://example.com/error-description + additionalProperties: false + description: Контейнер с ошибкой + OBRUErrorResponseErrorCode: + type: string + description: "Низкоуровневое описание ошибки. Поставщик услуг должен заполни\ + ть сообщение детальным описанием ошибки, не раскрывая конфиденциальную инф\ + ормацию." + example: RU.CBR.Field.Missing + enum: + - RU.CBR.Field.Expected + - RU.CBR.Field.Invalid + - RU.CBR.Field.InvalidDate + - RU.CBR.Field.Missing + - RU.CBR.Header.Invalid + - RU.CBR.Header.Missing + - RU.CBR.Resource.InvalidFormat + - RU.CBR.Resource.NotFound + - RU.CBR.Resource.NotCreated + - RU.CBR.Rules.AfterCutOffDateTime + - RU.CBR.Signature.Invalid + - RU.CBR.Signature.InvalidClaim + - RU.CBR.Signature.MissingClaim + - RU.CBR.Signature.Malformed + - RU.CBR.Signature.Missing + - RU.CBR.Unsupported.AccountIdentifier + - RU.CBR.Unsupported.LocalInstrument + - RU.CBR.Authenticate.InvalidScope + - RU.CBR.Authenticate.InvalidConsent + - RU.CBR.Rules.ResourceAlreadyExists + - RU.CBR.UnexpectedError + x-enum-descriptions: + - "(HTTP статус 400). Если поля передаются парой (ключ-значение) и значение\ + \ не было передано. В поле path должен передаваться путь к ожидаемому полю\ + \ (например, ErrorResponse.Errors.path == “AccountResponse.Data.Account.AccountDetails.identification”\ + ). Например, для допустимого значения поля «schemeName» должно передаватьс\ + я соответствующее значение идентификатора в поле «identification»." + - "(HTTP статус 400).В поле указано недопустимое значение или длина предоста\ + вленного значения превышает соответствующую максимальную длину поля в доме\ + не ППИУ. Ссылка на недопустимое поле должна быть указана в поле path (напр\ + имер,ErrorResponse.Errors.path == “AccountResponse.Data.Account.AccountDetails.schemeName”\ + ). В поле URL может быть ссылка на веб-страницу, объясняющую правильное по\ + ведение. Проблема должна быть подробно описана в сообщении об ошибке (поле\ + \ ErrorResponse.Errors.message)." + - "(HTTP статус 400).Указана неверная дата. Например, когда ожидается будуща\ + я дата, а указана дата в прошлом или текущая дата. В сообщении можно указа\ + ть актуальную проблему с датой. Ссылка на недопустимое поле должна быть ук\ + азана в поле path, а в поле URL может быть ссылка на веб-страницу, объясня\ + ющую правильное поведение." + - "(HTTP статус 400).Обязательное поле, необходимое для API, отсутствует в п\ + олезной нагрузке. Данный код ошибки можно использовать, если ошибка еще не\ + \ определена при проверке RU.CBR.Resource.InvalidFormat. Ссылка на отсутст\ + вующее поле должна быть указана в поле path, а в поле URL может быть ссылк\ + а на веб-страницу, объясняющую правильное поведение." + - (HTTP статус 400).В элементе заголовка HTTP указано неверное значение. Элемент + заголовка HTTP должен быть указан в элементе пути. + - "(HTTP статус 400).Обязательный элемент HTTP-заголовка не был предоставлен\ + . Элемент заголовка HTTP должен быть указан в элементе path. Элемент пути\ + \ кода ошибки должен быть заполнен элементом ресурса согласия, который явл\ + яется недопустимым." + - "(HTTP статус 400).Json-схема полезной нагрузки не соответствует конечной\ + \ точке. Например, конечная точка POST /account-consents вызывается с поле\ + зной нагрузкой JSON, которая не может быть проанализирована в классе ConsentRequest." + - (HTTP статус 400).Ресурс с указанным идентификатором не существует или не + может быть обработан (в том числе неприемлимый формат или значение идентификатора + ресурса). + - "(HTTP статус 400).Ресурс с указанным идентификатором еще не создан и не м\ + ожет быть передан в ответном сообщении. Для асинхронных вызовов. Например\ + , получение выписки по счету, где сначала создается ресурс выписки (метод\ + \ POST /statements/{accountId}) и в ответном сообщение приходит идентифика\ + тор созданного ресурса выписки, но для наполнения выписки данными ППИУ тре\ + буется некоторое время. Соответственно, будет приходить данное сообщение о\ + б ошибке." + - (HTTP статус 400).Ресурс согласия или ресурс платежа запрашиваются после даты + CutOffDateTime. + - "(HTTP статус 400).Заголовок подписи x-jws-signature был проанализирован и\ + \ имеет действительный заголовок JOSE, соответствующий спецификации. Но са\ + ма подпись не может быть проверена." + - "(HTTP статус 400).Заголовок JOSE в элементе x-jws-signature имеет одно ил\ + и несколько утверждений (claim) с недопустимым значением. (например, утвер\ + ждение kid, которое не принимает сертификат). Наименование отсутствующего\ + \ утверждения должно передаваться в поле path ответа об ошибке." + - "(HTTP статус 400).Заголовок JOSE в элементе x-jws-signature имеет одно ил\ + и несколько обязательных утверждений, которые не указаны. Имя пропущенного\ + \ утверждения должно быть указано в поле path ответа об ошибке." + - (HTTP статус 400).x-jws-signature в заголовке запроса была искажена и не могла + быть проанализирована как допустимый JWS. + - "(HTTP статус 400).Запрос API предполагает x-jws-signature в заголовке, но\ + \ элемент отсутствовал." + - (HTTP статус 400).Идентификатор счета не поддерживается для данной схемы. + Элемент path должен быть заполнен путем к элементу accountIdentifier. + - (HTTP статус 400).Указанный localInstrument не поддерживается ППИУ. Элемент + path должен быть заполнен путем к элементу localInstrument. Элемент URL должен + быть заполнен ссылкой на документацию ППИУ со списком поддерживаемых localInstrument. + - (HTTP статус 403).Предъявленный токен доступа не содержит область действия + ("scope") необходимый для доступа к ресурсу. + - "(HTTP статус 403).Отказано доступу к ресурсу с указанным идентификатором\ + , так как согласие Пользователя, отсутствует, либо имеет не корректный ста\ + тус, либо не содержит необходимых разрешений (\"pernissions\") на данный р\ + есурс." + - (HTTP статус 409).Ресурс с такими же параметрами уже существует. + - "(HTTP статус 5xx).Данный код ошибки можно использовать при возникновении\ + \ непредвиденной ошибки. ППИУ должен заполнить сообщение детальным описани\ + ем ошибки, не раскрывая конфиденциальную информацию." + x-enum-varnames: + - FieldExpected + - FieldInvalid + - FieldInvalidDate + - FieldMissing + - HeaderInvalid + - HeaderMissing + - ResourceInvalidFormat + - ResourceNotFound + - ResourceNotCreated + - RulesAfterCutOffDateTime + - SignatureInvalid + - SignatureInvalidClaim + - SignatureMissingClaim + - SignatureMalformed + - SignatureMissing + - UnsupportedAccountIdentifier + - UnsupportedLocalInstrument + - AuthenticateInvalidScope + - AuthenticateInvalidConsent + - RulesResourceAlreadyExists + - UnexpectedError + StatementResponse: + maxProperties: 3 + minProperties: 3 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/StatementResponse_Data' + Links: + $ref: '#/components/schemas/StatementResponse_Links' + Meta: + $ref: '#/components/schemas/AccountResponse_Meta' + additionalProperties: false + description: Ответ запроса на выписку + example: + Data: + statementId: this-is-a-slug-format-statement-id + accountId: this-is-a-slug-format-account-id + fromBookingDateTime: 2019-09-15T00:00:00+00:00 + toBookingDateTime: 2019-12-15T00:00:00+00:00 + creationDateTime: 2021-06-05T15:15:13+00:00 + Balance: + - creditDebitIndicator: Debit + type: ClosingAvailable + Amount: + amount: "200.00" + currency: RUB + TransactionsSummary: + TotalCreditEntries: + numberOfEntries: "2" + sum: "100.00" + currency: RUB + TotalDebitEntries: + numberOfEntries: "2" + sum: "1500.00" + currency: RUB + Entry: + - transactionIdentification: this-is-a-slug-format-transaction-id + instructionIdentification: 12345-IID-001 + endtoendIdentification: 12345-EEID-001 + uetr: de2da6c9-18be-48d4-8053-867ed90a316a + purpose: "1" + creditDebitIndicator: Debit + status: AcceptedSettlementCompleted + bookingDateTime: 2023-12-15T00:00:00+00:00 + accDocDate: 2021-01-01 + valueDateTime: 2023-12-15T00:00:00+00:00 + Amount: + amount: "200.00" + currency: RUB + TransactionAmount: + amount: "200.00" + currency: RUB + ChargeAmount: + amount: "200.00" + currency: RUB + InstructedAmount: + Amount: + amount: "200.00" + currency: RUB + CurrencyExchange: + sourceCurrency: RUB + targetCurrency: RUB + unitCurrency: RUB + exchangeRate: "0.7" + contractIdentification: DOC441234-1234-1234 + quotationDate: 2021-06-05T15:15:13+00:00 + BankTransactionCode: + code: "20" + subCode: "20" + issuer: RU.CBR + PaymentTypeInformation: + localInstrument: "01" + categoryPurpose: "1" + serviceLevel: URGP + UltimateDebtor: + name: Наименование организации или физического лица + mobileNumber: "79206001010" + countryOfResidence: RU + countryOfBirth: RU + provinceOfBirth: Ставропольский край + cityOfBirth: Ставрополь + birthDate: 2021-06-05T15:15:13+00:00 + Identification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + Debtor: + Agent: + name: Наименование организации или физического лица + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "9612123" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + Party: + name: Наименование организации или физического лица + mobileNumber: "79206001010" + countryOfResidence: RU + countryOfBirth: RU + provinceOfBirth: Ставропольский край + cityOfBirth: Ставрополь + birthDate: 2021-06-05T15:15:13+00:00 + Identification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + DebtorAgent: + schemeName: RU.CBR.BIC + identification: "9612123" + DebtorAgentAccount: + name: Основной счет + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + DebtorAccount: + name: Основной счет + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + IntermediaryAgent: + schemeName: RU.CBR.BIC + identification: "9612123" + IntermediaryAgentAccount: + name: Основной счет + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + CreditorAgent: + schemeName: RU.CBR.BIC + identification: "9612123" + CreditorAccount: + name: Основной счет + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + CreditorAgentAccount: + name: Основной счет + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + Creditor: + Agent: + name: Наименование организации или физического лица + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "9612123" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "40817810621234570000" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + Party: + name: Наименование организации или физического лица + mobileNumber: "79206001010" + countryOfResidence: RU + countryOfBirth: RU + provinceOfBirth: Ставропольский край + cityOfBirth: Ставрополь + birthDate: 2021-06-05T15:15:13+00:00 + Identification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + UltimateCreditor: + name: Наименование организации или физического лица + mobileNumber: "79206001010" + countryOfResidence: RU + countryOfBirth: RU + provinceOfBirth: Ставропольский край + cityOfBirth: Ставрополь + birthDate: 2021-06-05T15:15:13+00:00 + Identification: + - schemeName: RU.CBR.TXID + identification: "7728240240" + PostalAddress: + addressType: Postal + addressLine: + - Адрес в виде строки + - вторая часть строки адреса + streetName: Садовая + buildingNumber: "11" + postCode: "0100010" + townName: Бигсити + countrySubDivision: Мой край + country: RU + CardTransaction: + Card: + PlainCardData: + PAN: '*0001' + cardSequenceNumber: "01" + effectiveDate: 12/2021 + expiryDate: 12/2025 + serviceCode: "121" + TrackData: + - trackNumber: string + trackValue: string + CardSecurityCode: + CSCManagement: CSCPresent + CSCValue: "123" + cardCountryCode: "643" + CardBrand: + identification: string + type: ACCP + additionalCardData: Дополнительные сведения + POI: + Identification: + identification: string + type: ACCP + systemName: string + groupIdentification: string + Component: + - POIComponentType: CHIT + manufacturerIdentification: manufacturerIdentification + model: model + versionNumber: versionNumber + serialNumber: serialNumber + approvalNumber: approvalNumber + Transaction: + transactionCategory: stri + sequenceNumber: string + TransactionIdentification: + transactionDateTime: 2021-06-05T15:15:13+00:00 + transactionReference: string + Product: + - productCode: string + unitOfMeasure: KILO + productQuantity: "10.2" + unitPrice: "200.00" + productAmount: "200.00" + taxType: string + additionalProductInformation: string + authorizationCode: string + RemittanceInformation: + unstructured: Назначение платежа - оплата за товары или услуги + ReferredDocumentInformation: + - Type: "0" + Number: "0" + RelatedDate: 2021-06-05T15:15:13+00:00 + CreditorReferenceInformation: + type: ИПД + reference: CBR-130 + TaxRemittance: + administrationZone: "45388000" + referenceNumber: "120" + date: 2021-06-05T15:15:13+00:00 + creditor: + taxType: "991230001" + registrationIdentification: aa-12340 + debtor: + taxType: "991230001" + registrationIdentification: aa-12340 + Record: + type: "1234" + category: TP + categoryDetails: "18210301000011000000" + debtorStatus: "13" + Period: + - year: 2021-01-01 + type: MM02 + fromDate: 2021-06-05T15:15:13+00:00 + toDate: 2021-06-05T15:15:13+00:00 + TaxAmount: + rate: "20" + totalAmount: "200.00" + Links: + self: https://sb.example.ru/v1.3/example?page=1 + first: https://sb.example.ru/v1.3/example?page=1 + prev: https://sb.example.ru/v1.3/example?page=1 + next: https://sb.example.ru/v1.3/example?page=1 + last: https://sb.example.ru/v1.3/example?page=1 + Meta: + totalPages: 1 + Statement_2: + required: + - accountId + - creationDateTime + - fromBookingDateTime + - statementId + - toBookingDateTime + type: object + properties: + statementId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: Идентификатор ресурса выписки + example: this-is-a-slug-format-statement-id + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса accounts" + example: this-is-a-slug-format-account-id + fromBookingDateTime: + description: Дата и время начала выписки + example: 2019-09-15T00:00:00+00:00 + allOf: + - $ref: '#/components/schemas/ISODateTime' + toBookingDateTime: + description: Дата и время окончания выписки + example: 2019-12-15T00:00:00+00:00 + allOf: + - $ref: '#/components/schemas/ISODateTime' + creationDateTime: + description: Дата и время создания ресурса + allOf: + - $ref: '#/components/schemas/ISODateTime' + Balance: + maxItems: 10 + minItems: 0 + type: array + description: "Информация об остатках по счету (например, в массиве можно\ + \ указать значения на начало и конец операционного дня)" + items: + $ref: '#/components/schemas/CashBalance' + TransactionsSummary: + $ref: '#/components/schemas/Statement_2_TransactionsSummary' + Entry: + maxItems: 50 + minItems: 0 + type: array + description: Список операций + items: + $ref: '#/components/schemas/ReportEntry' + additionalProperties: false + description: Выписка по счету + CashBalance: + required: + - Amount + - creditDebitIndicator + - type + type: object + properties: + creditDebitIndicator: + description: Определяет является остаток кредитовым или дебетовым + allOf: + - $ref: '#/components/schemas/CreditDebitCode' + type: + description: Тип остатка + allOf: + - $ref: '#/components/schemas/BalanceType' + Amount: + $ref: '#/components/schemas/CashBalance_Amount' + additionalProperties: false + description: Детальная информация об остатке на счете + CreditDebitCode: + type: string + description: Признак дебета/кредита + example: Debit + enum: + - Credit + - Debit + x-enum-descriptions: + - Кредитовая операция по счету + - Дебетовая операция по счету + x-enum-varnames: + - Credit + - Debit + BalanceType: + type: string + description: Тип остатка + enum: + - ClosingAvailable + - ClosingBooked + - ClosingCleared + - Expected + - OpeningAvailable + - OpeningBooked + - OpeningCleared + - PreviouslyClosedBooked + x-enum-descriptions: + - "Конечный остаток суммы денег, которая находится в распоряжении владельца\ + \ счета на указанную дату" + - "Остаток по счету на конец предварительно согласованного отчетного периода\ + . Это сумма начального зарегистрированного баланса в начале периода и всех\ + \ записей, зачисленных на счет в течение предварительно согласованного отч\ + етного периода" + - "Конечный остаток суммы денег, которая очищается в указанную дату" + - "Баланс, состоящий из забронированных записей и отложенных позиций, извест\ + ных на момент расчета, который прогнозирует остаток на конец дня, если все\ + \ зарезервировано на счете и никакая другая запись не публикуется" + - "Начальный баланс суммы денег, которая находится в распоряжении владельца\ + \ счета на указанную дату" + - Баланс счета в начале отчетного периода. Он всегда равен балансу из предыдущего + отчета + - "Начальный баланс, который очищается в указанную дату" + - Остаток по счету за ранее закрытый отчетный период. Начальный зарегистрированный + баланс на новый период равен этому балансу + x-enum-varnames: + - ClosingAvailable + - ClosingBooked + - ClosingCleared + - Expected + - OpeningAvailable + - OpeningBooked + - OpeningCleared + - PreviouslyClosedBooked + ActiveOrHistoricCurrencyAndAmount: + required: + - amount + - currency + type: object + properties: + amount: + description: Сумма денежных средств + allOf: + - $ref: '#/components/schemas/ActiveCurrencyAndAmountSimpleType' + currency: + description: "Код валюты, соответствующий международному стандарту ISO 4217" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + additionalProperties: false + description: Сумма денежных средств и код валюты + ActiveCurrencyAndAmountSimpleType: + pattern: "^\\d{1,15}\\.\\d{2,4}$" + type: string + description: Сумма денежных средств + example: "200.00" + TransactionsSummary: + type: object + properties: + TotalCreditEntries: + $ref: '#/components/schemas/TransactionsSummary_TotalCreditEntries' + TotalDebitEntries: + $ref: '#/components/schemas/TransactionsSummary_TotalDebitEntries' + additionalProperties: false + description: Обороты по кредиту и дебету + NumberAndSumOfTransactions: + required: + - currency + - sum + type: object + properties: + numberOfEntries: + type: integer + description: Количество записей + format: int64 + sum: + description: Общая сумма всех записей + allOf: + - $ref: '#/components/schemas/ActiveCurrencyAndAmountSimpleType' + currency: + description: "Код валюты, соответствующий международному стандарту ISO 4217" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + additionalProperties: false + description: "Набор элементов, обеспечивающих общую сумму записей" + ReportEntry: + required: + - Amount + - bookingDateTime + - creditDebitIndicator + - status + type: object + properties: + transactionIdentification: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации операции по счету" + example: this-is-a-slug-format-transaction-id + instructionIdentification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Уникальный идентификатор, присвоенный инструктирующей стор\ + оной для инструктируемой стороны для однозначного определения инструкц\ + ии" + example: 12345-IID-001 + endtoendIdentification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,40}$" + type: string + description: "Уникальный идентификатор, присвоенный инструктирующей стор\ + оной для инструктируемой стороны для однозначного определения инструкц\ + ии" + example: 12345-EEID-001 + uetr: + maxLength: 36 + minLength: 1 + pattern: "[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}" + type: string + description: "Указывается идентификатор, присваиваемый при передаче расп\ + оряжения с использованием системы SWIFT, в соответствии со стандартом\ + \ RFC 4122 (IETF)" + example: de2da6c9-18be-48d4-8053-867ed90a316a + purpose: + description: "(Номер реквизита 15.5 Код вида дохода) Причина, по которой\ + \ осуществляется платеж." + allOf: + - $ref: '#/components/schemas/PurposeCode' + creditDebitIndicator: + description: Определяет является ли операция дебетовая или кредитовая + allOf: + - $ref: '#/components/schemas/CreditDebitCode' + status: + description: Статус операции по счету + allOf: + - $ref: '#/components/schemas/TransactionStatusCode' + bookingDateTime: + type: string + description: "Дата и время, когда запись об операции по счету публикуетс\ + я на счете в бухгалтерской книге обслуживающей организации. Использует\ + ся стандарт ISO8601" + format: date-time + example: 2023-12-15T00:00:00Z + accDocDate: + type: string + description: "-> Дата составления распоряжения (!!! Примечание Проверить\ + \ реквизит о чем он? Не должно быть здесь, Дата распоряжение указывает\ + ся в RemittanceInformation/ReferredDocumentInformation/RelatedDate вме\ + сте с номером)" + format: date + example: 2021-01-01 + valueDateTime: + type: string + description: "Дата и время, когда активы становятся доступными владельцу\ + \ счета в случае ввода кредита или перестают быть доступными владельцу\ + \ счета в случае ввода дебетовой операции по счету" + format: date-time + example: 2023-12-15T00:00:00Z + Amount: + $ref: '#/components/schemas/ReportEntry_Amount' + TransactionAmount: + $ref: '#/components/schemas/ReportEntry_TransactionAmount' + ChargeAmount: + $ref: '#/components/schemas/ReportEntry_ChargeAmount' + InstructedAmount: + $ref: '#/components/schemas/ReportEntry_InstructedAmount' + BankTransactionCode: + $ref: '#/components/schemas/ReportEntry_BankTransactionCode' + PaymentTypeInformation: + $ref: '#/components/schemas/ReportEntry_PaymentTypeInformation' + UltimateDebtor: + $ref: '#/components/schemas/ReportEntry_UltimateDebtor' + Debtor: + $ref: '#/components/schemas/ReportEntry_Debtor' + DebtorAgent: + $ref: '#/components/schemas/ReportEntry_DebtorAgent' + DebtorAgentAccount: + $ref: '#/components/schemas/ReportEntry_DebtorAgentAccount' + DebtorAccount: + $ref: '#/components/schemas/ReportEntry_DebtorAccount' + IntermediaryAgent: + $ref: '#/components/schemas/ReportEntry_IntermediaryAgent' + IntermediaryAgentAccount: + $ref: '#/components/schemas/ReportEntry_IntermediaryAgentAccount' + CreditorAgent: + $ref: '#/components/schemas/ReportEntry_CreditorAgent' + CreditorAccount: + $ref: '#/components/schemas/ReportEntry_CreditorAccount' + CreditorAgentAccount: + $ref: '#/components/schemas/ReportEntry_CreditorAgentAccount' + Creditor: + $ref: '#/components/schemas/ReportEntry_Creditor' + UltimateCreditor: + $ref: '#/components/schemas/ReportEntry_UltimateCreditor' + CardTransaction: + $ref: '#/components/schemas/ReportEntry_CardTransaction' + RemittanceInformation: + $ref: '#/components/schemas/ReportEntry_RemittanceInformation' + additionalProperties: false + description: Запись об операция по счету + PurposeCode: + type: string + description: "Код вида дохода -причина, по которой осуществляется платеж." + example: "1" + enum: + - "1" + - "2" + - "3" + x-enum-descriptions: + - "При переводе денежных средств, являющихся заработной платой и (или) иными\ + \ доходами;" + - "При переводе денежных средств, являющихся доходами, на которые не может\ + \ быть обращено взыскание;" + - "При переводе денежных средств, являющихся доходами, к которым ограничения\ + \ по обращению взыскания не применяются." + x-enum-varnames: + - _1 + - _2 + - _3 + TransactionStatusCode: + type: string + description: Статус записи операции по счету + example: AcceptedSettlementCompleted + enum: + - AcceptedCreditSettlementCompleted + - AcceptedSettlementCompleted + - AcceptedSettlementInProcess + - AcceptedWithoutPosting + - Pending + - Rejected + x-enum-descriptions: + - Расчет по счету Получателя средств завершен + - Расчет по счету Плательщика завершен + - "Все предыдущие проверки, такие как техническая проверка и профиль клиента\ + , были успешными, и поэтому запрос об инициировании платежа был принят к и\ + сполнению" + - "Платежная инструкция, включенная в перевод, принимается без зачисления на\ + \ счет Получателя средств" + - "Ожидается инициирование группы платежей или отдельного платежа, включенно\ + го в группу платежей" + - "Инициирование группы платежей или отдельного платежа, включенная в группу\ + \ инициирования платежей, были отклонены" + x-enum-varnames: + - AcceptedCreditSettlementCompleted + - AcceptedSettlementCompleted + - AcceptedSettlementInProcess + - AcceptedWithoutPosting + - Pending + - Rejected + AmountAndCurrencyExchangeDetails: + type: object + properties: + Amount: + $ref: '#/components/schemas/AmountAndCurrencyExchangeDetails_Amount' + CurrencyExchange: + $ref: '#/components/schemas/AmountAndCurrencyExchangeDetails_CurrencyExchange' + additionalProperties: false + description: "Сумма денег и информации об обменом курсе, подлежащая перевод\ + у между плательщиком и получателем денежных средств до вычета расходов, вы\ + раженная в валюте обозначенной инициирующей стороной в случае, если указан\ + ная сумма и/или валюта отличаются от суммы и/или валюты операции по счету" + CurrencyExchange: + required: + - exchangeRate + - sourceCurrency + type: object + properties: + sourceCurrency: + description: "Валюта, из которой необходимо конвертировать сумму" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + targetCurrency: + description: "Валюта, в которую необходимо конвертировать сумму" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + unitCurrency: + description: "Валюта, в которой обменный курс выражен" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + exchangeRate: + maxLength: 12 + minLength: 1 + pattern: "^[\\w\\W]{1,12}$" + type: string + description: "Коэффициент, используемый для перевода суммы из одной валю\ + ты в другую. Это отражает цену, по которой одна валюта была куплена за\ + \ другую валюту" + example: "0.7" + contractIdentification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Идентификатор для однозначного определения валютного контракта + example: DOC441234-1234-1234 + quotationDate: + description: Дата и время обменного курса + allOf: + - $ref: '#/components/schemas/ISODateTime' + additionalProperties: false + description: Подробная информация об обмене валюты + BankTransactionCode: + required: + - code + type: object + properties: + code: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Тип банковской операции + example: "20" + subCode: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Подтип банковской операции + example: "20" + issuer: + maxLength: 35 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Идентификация эмитента собственного банковского кода операции + по счету + example: RU.CBR + additionalProperties: false + description: Код банковской операции + PaymentTypeInformation: + type: object + properties: + localInstrument: + description: "(Номер реквизита 5) Вид распоряжения. Этот элемент использ\ + уется для указания локального инструмента, опции локального клиринга и\ + \ / или дальнейшей квалификации услуги или уровня обслуживания или Вид\ + \ платежного распоряжения" + allOf: + - $ref: '#/components/schemas/LocalInstrumentCode' + categoryPurpose: + type: string + description: | + (Номер реквизита 15.3) Категория назначения. Очередность платежа + Применение: Поле может принимать значение в диапазоне 0-5. Значение + поля должно быть равно 0, если в соответствии с нормативными актами Банка + России очередность платежа не применяется + example: "1" + enum: + - "0" + - "1" + - "2" + - "3" + - "4" + - "5" + serviceLevel: + description: (Номер реквизита 15.1) Вид платежа + allOf: + - $ref: '#/components/schemas/ServiceLevelCode' + additionalProperties: false + description: Информация о платеже + LocalInstrumentCode: + maxLength: 35 + type: string + description: яч или код платежной системы или код платежного инструмента (требует + уточнения) + enum: + - "01" + - "02" + - "06" + - "16" + - "17" + - "09" + x-enum-descriptions: + - Кредитовый перевод + x-enum-varnames: + - _01 + ServiceLevelCode: + type: string + description: Вид платежа + enum: + - URGP + - NURG + x-enum-descriptions: + - Срочный + - Не срочный + x-enum-varnames: + - URGP + - NURG + PartyChoice: + maxProperties: 1 + minProperties: 1 + type: object + properties: + Agent: + $ref: '#/components/schemas/PartyChoice_Agent' + Party: + $ref: '#/components/schemas/PartyChoice_Party' + additionalProperties: false + description: "Информация об участнике, используемая для идентификации юридич\ + еского, физического лица или финансовой организации" + CardTransaction18: + type: object + properties: + Card: + $ref: '#/components/schemas/PaymentCard4' + POI: + $ref: '#/components/schemas/CardTransaction18_POI' + Transaction: + $ref: '#/components/schemas/CardTransaction18_Transaction' + additionalProperties: false + description: "Предоставляет данные по карте (номер, платежная система), терм\ + иналу (номер, идентификатор) и транзакционные данные, используемые для уни\ + кальной идентификации операции по карте" + PaymentCard4: + type: object + properties: + PlainCardData: + $ref: '#/components/schemas/PaymentCard4_PlainCardData' + cardCountryCode: + description: "Код страны, присвоенный карте эмитентом карты" + allOf: + - $ref: '#/components/schemas/CountryCodeNumeric' + CardBrand: + $ref: '#/components/schemas/PaymentCard4_CardBrand' + additionalCardData: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: "Дополнительные сведения, специфичные для эмитента карты" + example: Дополнительные сведения + additionalProperties: false + description: Данные по платежной карте + PlainCardData1: + required: + - PAN + - expiryDate + type: object + properties: + PAN: + pattern: "^[*0-9]{4,28}$" + type: string + description: Основной учетный номер карты (PAN) или номер карты + example: '*0001' + cardSequenceNumber: + pattern: "^[0-9]{2,3}$" + type: string + description: Идентификатор карты среди множества карт с одинаковым номером + карты (PAN) + example: "01" + effectiveDate: + description: "Дата, начиная с которой карту можно использовать" + example: 12/2021 + allOf: + - $ref: '#/components/schemas/ISOYearMonth' + expiryDate: + description: Дата окончания срока действия карты + example: 12/2025 + allOf: + - $ref: '#/components/schemas/ISOYearMonth' + serviceCode: + pattern: "^[0-9]{3}$" + type: string + description: Услуги по карте в соответствии с ISO 7813 + example: "121" + TrackData: + maxItems: 1000 + type: array + description: Данные магнитной дорожки платежной карты или их эквивалент + items: + $ref: '#/components/schemas/TrackData1' + CardSecurityCode: + $ref: '#/components/schemas/PlainCardData1_CardSecurityCode' + additionalProperties: false + description: "Конфиденциальные данные, связанные с выполнением операции по к\ + арте" + ISOYearMonth: + pattern: "^(1[0-2]|0[1-9]|\\d)\\/([2-9]\\d[1-9]\\d|[1-9]\\d)$" + type: string + description: Формат даты год и месяц + example: 12/2025 + TrackData1: + required: + - trackValue + type: object + properties: + trackNumber: + pattern: "^[0-9]$" + type: string + description: Номер дорожки карты + trackValue: + maxLength: 140 + minLength: 1 + pattern: "^[\\w\\W]{1,140}$" + type: string + description: Содержание дорожки карты или его эквивалент + additionalProperties: false + description: Данные магнитной дорожки платежной карты или их эквивалент + CardSecurityInformation1: + required: + - CSCManagement + type: object + properties: + CSCManagement: + $ref: '#/components/schemas/CSCManagement1Code' + CSCValue: + pattern: "^[0-9]{3,4}$" + type: string + description: Код безопасности карты + example: "123" + additionalProperties: false + description: "Код безопасности карты (CSC), связанный с выполнением операции\ + \ по карте" + CSCManagement1Code: + type: string + description: Управление кодом безопасности карты (CSC) в связи с операцией + enum: + - CSCPresent + - CSCByPass + - CSCUnread + - NoCSC + CountryCodeNumeric: + pattern: "^[0-9]{3}$" + type: string + description: Код страны по ISO-3166-1 в форме трехзначного цифрового кода + example: "643" + GenericIdentification32: + required: + - identification + type: object + properties: + identification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Идентификатор субъекта + type: + $ref: '#/components/schemas/PartyType3Code' + additionalProperties: false + description: "Информация, связанная с идентификацией" + PartyType3Code: + type: string + description: Тип субъекта + example: ACCP + enum: + - OPOI + - MERC + - ACCP + - ITAG + - ACQR + - CISS + - DLIS + PointOfInteraction1: + required: + - Identification + type: object + properties: + Identification: + $ref: '#/components/schemas/PointOfInteraction1_Identification' + systemName: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: "Общее название, присвоенное эквайером POI-системе" + groupIdentification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Идентификатор, присвоенный торгово-сервисной организацией\ + , идентифицирующий множество POI-терминалов, выполняющих некоторые кат\ + егории операций" + Component: + maxItems: 1000 + type: array + description: "Данные, относящиеся к компоненту POI, выполняющему операци\ + ю" + items: + $ref: '#/components/schemas/PointOfInteractionComponent1' + additionalProperties: false + description: "Точка взаимодействия, выполняющая транзакцию" + PointOfInteractionComponent1: + required: + - POIComponentType + type: object + properties: + POIComponentType: + $ref: '#/components/schemas/POIComponentType1Code' + manufacturerIdentification: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Идентификатор поставщика программного обеспечения, аппарат\ + ной части или системы компонента POI-терминала" + example: manufacturerIdentification + model: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Идентификатор модели компонента POI-терминала для определенного + производителя + example: model + versionNumber: + maxLength: 16 + minLength: 1 + pattern: "^[\\w\\W]{1,16}$" + type: string + description: "Версия компонента, являющегося частью определенной модели" + example: versionNumber + serialNumber: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Серийный номер компонента + example: serialNumber + approvalNumber: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: "Уникальный регистрационный номер компонента, предоставленн\ + ый органом сертификации" + example: approvalNumber + additionalProperties: false + description: "Данные, относящиеся к компоненту POI, выполняющему операцию" + POIComponentType1Code: + type: string + description: "Тип компонента, являющегося частью POI-терминала" + example: CHIT + enum: + - SOFT + - EMVK + - EMVO + - MRIT + - CHIT + - SECM + - PEDV + CardIndividualTransaction2: + type: object + properties: + transactionCategory: + maxLength: 4 + minLength: 1 + pattern: "^[\\w\\W]{1,4}$" + type: string + description: "Код категории соответствует ISO 18245 и относится к типу у\ + слуг или товаров, которые продавец предоставляет для транзакции" + sequenceNumber: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Порядковый номер транзакции по карте, назначенный POI (точ\ + ка взаимодействия)" + TransactionIdentification: + $ref: '#/components/schemas/CardIndividualTransaction2_TransactionIdentification' + Product: + maxItems: 1000 + type: array + description: "Товар, заказанный по операции" + items: + $ref: '#/components/schemas/CardIndividualTransaction2_Product_inner' + authorizationCode: + maxLength: 35 + minLength: 3 + pattern: "^[\\w\\W]{3,35}$" + type: string + description: Код авторизации операции + additionalProperties: false + description: "Сведения об отдельной операции по карте, записанные на POI-тер\ + минале (точке взаимодействия)" + TransactionIdentifier1: + required: + - transactionDateTime + - transactionReference + type: object + properties: + transactionDateTime: + description: Дата и время основной операции (присвоенные POI-терминалом + (точкой взаимодействия) + allOf: + - $ref: '#/components/schemas/ISODateTime' + transactionReference: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Идентификатор операции, который должен быть уникальным в т\ + ечение периода времени" + additionalProperties: false + description: Идентификация операции однозначным способом + Product2: + required: + - productCode + type: object + properties: + productCode: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: Код продукта + unitOfMeasure: + $ref: '#/components/schemas/UnitOfMeasure1Code' + productQuantity: + pattern: "^[0-9]{1,18}$|^[0-9]{1,18}[.][0-9]{1,18}$" + type: string + description: Количество товара + example: "10.2" + unitPrice: + pattern: "^\\d{1,15}\\.\\d{2,4}$" + type: string + description: Сумма денежных средств + example: "200.00" + productAmount: + pattern: "^\\d{1,15}\\.\\d{2,4}$" + type: string + description: Сумма денежных средств + example: "200.00" + taxType: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Информация об уплачиваемом налоге на товар + additionalProductInformation: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Дополнительная информация о товаре + additionalProperties: false + description: Информация о продукте + UnitOfMeasure1Code: + type: string + description: Единица измерения приобретаемой позиции + example: KILO + enum: + - PIEC + - TONS + - FOOT + - GBGA + - USGA + - GRAM + - INCH + - KILO + - PUND + - METR + - CMET + - MMET + - LITR + - CELI + - MILI + - GBOU + - USOU + - GBQA + - USQA + - GBPI + - USPI + - MILE + - KMET + - YARD + - SQKI + - HECT + - ARES + - SMET + - SCMT + - SMIL + - SQMI + - SQYA + - SQFO + - SQIN + - ACRE + RemittanceInformation: + required: + - unstructured + type: object + properties: + unstructured: + maxLength: 140 + minLength: 1 + pattern: "^[\\w\\W]{1,140}$" + type: string + description: Текстовое назначение платежа + example: Назначение платежа - оплата за товары или услуги + ReferredDocumentInformation: + maxItems: 50 + minItems: 0 + type: array + description: Информация о связанном документе. В первом повторении секции + ReferredDocumentInformation указывается Дата составления распоряжения. + По договоренности участников обмена могут быть указаны иные коды связанных + документов в последующих повторениях секции ReferredDocumentInformation. + items: + $ref: '#/components/schemas/ReferredDocumentInformation' + CreditorReferenceInformation: + $ref: '#/components/schemas/RemittanceInformation_CreditorReferenceInformation' + TaxRemittance: + $ref: '#/components/schemas/RemittanceInformation_TaxRemittance' + additionalProperties: false + description: "Назначение платежа. Предоставляемая информация, позволяющая со\ + поставить запись с позициями, для которых предназначен перевод" + ReferredDocumentInformation: + type: object + properties: + Type: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Тип связанного документа + example: "0" + Number: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Номер связанного документа + example: "0" + RelatedDate: + description: Дата связанного документа + allOf: + - $ref: '#/components/schemas/ISODateTime' + additionalProperties: false + description: Информация о связанном документе. В первом повторении секции ReferredDocumentInformation + указывается Дата составления распоряжения. По договоренности участников обмена + могут быть указаны иные коды связанных документов в последующих повторениях + секции ReferredDocumentInformation. + CreditorReferenceInformation: + type: object + properties: + type: + maxLength: 35 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Тип идентификатора платежа (Номер реквизита 15.6.n) + example: ИПД + reference: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Значение идентификатора платежа (Номер реквизита 15.7.n).\ + \ Ссылка, присвоенная получателем денежных средств, которая является о\ + снованием для осуществления перевода" + example: CBR-130 + additionalProperties: false + description: "Информация о референсах, предоставленная получателем денежных\ + \ средств, позволяющая идентифицировать исходные документы." + TaxInformation: + type: object + properties: + administrationZone: + maxLength: 11 + pattern: "^\\d{1,11}$" + type: string + description: Реквизит 105. Код по Общероссийскому классификатору территорий + муниципальных образований ОКТМО + example: "45388000" + referenceNumber: + maxLength: 140 + minLength: 1 + pattern: "^[\\w\\W]{1,140}$" + type: string + description: Реквизит 108. Номер налогового документа + example: "120" + date: + description: Реквизит 109. Дата налогового документа + allOf: + - $ref: '#/components/schemas/ISODateTime' + creditor: + $ref: '#/components/schemas/TaxInformation_creditor' + debtor: + $ref: '#/components/schemas/TaxInformation_debtor' + Record: + $ref: '#/components/schemas/TaxInformation_Record' + additionalProperties: false + description: Налоговая информация + TaxParty: + type: object + properties: + taxType: + pattern: "^\\d{9}$" + type: string + description: Код причины постановки на учет (КПП) + example: "991230001" + registrationIdentification: + maxLength: 35 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Реквизит 107. Код таможенного органа (Поле заполняется для + распоряжений по уплате таможенных платежей) + example: aa-12340 + additionalProperties: false + description: Налоговая информация об участнике перевода денежных средств + TaxRecord: + type: object + properties: + type: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Реквизит 110. Код выплат + example: "1234" + category: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Реквизит 106. Основание налогового платежа + example: TP + categoryDetails: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Код бюджетной классификации + example: "18210301000011000000" + debtorStatus: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: Статус налогоплательщика + example: "13" + Period: + maxItems: 50 + minItems: 0 + type: array + description: (Номер реквизита 14.2) Налоговый период + items: + $ref: '#/components/schemas/TaxPeriod' + TaxAmount: + $ref: '#/components/schemas/TaxRecord_TaxAmount' + additionalProperties: false + description: Дополнительные налоговые реквизиты + TaxPeriod: + type: object + properties: + year: + pattern: "^([1-9][0-9]{3}|0[0-9]{3})-01-01$" + type: string + description: "Год, к которому относится налог" + example: 2021-01-01 + type: + description: Тип налогового периода (реквизит 107) + example: MM02 + allOf: + - $ref: '#/components/schemas/TaxRecordPeriodCode' + fromDate: + description: Дата уплаты налогового платежа + allOf: + - $ref: '#/components/schemas/ISODateTime' + toDate: + description: Дата уплаты налогового платежа + allOf: + - $ref: '#/components/schemas/ISODateTime' + additionalProperties: false + description: Налоговый период + TaxRecordPeriodCode: + type: string + description: Тип налогового периода (реквизит 107) + example: MM02 + enum: + - MM01 + - MM02 + - MM03 + - MM04 + - MM05 + - MM06 + - MM07 + - MM08 + - MM09 + - MM10 + - MM11 + - MM12 + - QTR1 + - QTR2 + - QTR3 + - QTR4 + - HLF1 + - HLF2 + x-enum-descriptions: + - Январь + - Февраль + - Март + - Апрель + - Май + - Июнь + - Июль + - Август + - Сентябрь + - Октябрь + - Ноябрь + - Декабрь + - Первый квартал + - Второй квартал + - Третий квартал + - Четвертый квартал + - Первое полугодие + - Второе полугодие + x-enum-varnames: + - MM01 + - MM02 + - MM03 + - MM04 + - MM05 + - MM06 + - MM07 + - MM08 + - MM09 + - MM10 + - MM11 + - MM12 + - QTR1 + - QTR2 + - QTR3 + - QTR4 + - HLF1 + - HLF2 + TaxAmount: + type: object + properties: + rate: + description: Ставка НДС (Номер реквизита 14.3) + allOf: + - $ref: '#/components/schemas/CBRFTaxRate' + totalAmount: + description: Сумма НДС (Номер реквизита 14.4) + allOf: + - $ref: '#/components/schemas/ActiveCurrencyAndAmountSimpleType' + additionalProperties: false + description: Информация о НДС + CBRFTaxRate: + pattern: "^\\d{1,2}$" + type: string + description: Процентная ставка НДС + example: "20" + StatementInitRequest: + maxProperties: 1 + minProperties: 1 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/StatementInitRequest_Data' + additionalProperties: false + description: Запрос создания ресурса выписки + example: + Data: null + DataStatementInitRequest: + required: + - Statement + type: object + properties: + Statement: + $ref: '#/components/schemas/DataStatementInitRequest_Statement' + additionalProperties: false + description: Запрос создания ресурса выписки + StatementInitType: + required: + - accountId + - fromBookingDateTime + - toBookingDateTime + type: object + properties: + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: Идентификатор ресурса счета + example: this-is-a-slug-format-account-id + fromBookingDateTime: + description: "Дата и время начала расчетов, представленных в выписке" + example: 2019-09-15T00:00:00+00:00 + allOf: + - $ref: '#/components/schemas/ISODateTime' + toBookingDateTime: + description: "Дата и время окончания расчетов, представленных в выписке" + example: 2019-12-15T00:00:00+00:00 + allOf: + - $ref: '#/components/schemas/ISODateTime' + additionalProperties: false + description: Объект запроса на создание ресурса выписки + StatementInitResponse: + maxProperties: 3 + minProperties: 3 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/StatementInitResponse_Data' + Links: + $ref: '#/components/schemas/AccountResponse_Links' + Meta: + $ref: '#/components/schemas/AccountResponse_Meta' + additionalProperties: false + description: Ответ на запрос создания ресурса выписки + example: + Meta: null + Links: + self: https://sb.example.ru/v1.3/example + Data: null + DataStatementInitResponse: + required: + - Statement + type: object + properties: + Statement: + $ref: '#/components/schemas/DataStatementInitResponse_Statement' + additionalProperties: false + description: Полезная нагрузка ответа запроса на создание выписки + StatementInitResponseType: + required: + - fromBookingDateTime + - statementId + - toBookingDateTime + type: object + properties: + statementId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: Идентификатор ресурса выписки + example: this-is-a-slug-format-statement-id + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: Идентификатор ресурса счета + example: this-is-a-slug-format-account-id + fromBookingDateTime: + type: string + description: Дата и время начала выписки + format: date-time + example: 2019-09-15T00:00:00Z + toBookingDateTime: + type: string + description: Дата и время окончания выписки + format: date-time + example: 2019-12-15T00:00:00Z + additionalProperties: false + description: Ресурс выписки + ResponseDN: + type: object + properties: + dn: + type: string + description: Данные DN(Distinguished Name) + example: "emailAddress=teterkina.natalya@gmail.com, CN=Тетеркина Наталья\ + \ Геннадьевна, C=RU, SN=Тетеркина, GN=Наталья" + description: Данные DN(Distinguished Name) + example: + dn: "emailAddress=teterkina.natalya@gmail.com, CN=Тетеркина Наталья Геннад\ + ьевна, C=RU, SN=Тетеркина, GN=Наталья" + ResponseDNcnf: + type: string + description: Данные DN(Distinguished Name) пользователя файлом в формате .cnf + example: |- + [req] + prompt = no + distinguished_name = dn + req_extensions = ext + + [dn] + C = RU + SN = Тетеркина + GN = Наталья + CN = Тетеркина Наталья Геннадьевна + emailAddress = User860@pochtochka.com + + [ext] + RequestIssueRSACertificate: + type: object + properties: + tokenSerialNumber: + type: string + description: Серийный номер USB ключа + example: 00a81050 + pkcs10Content: + type: string + description: Контект PKCS10 + example: '-----BEGIN CERTIFICATE REQUEST-----\nMIIC3zCCAccCAQAwgZkxCzAJBgNVBAYTAlJVMRUwEwYDVQQEDAzQldGE0LjQvNC+\n0LIxFTATBgNVBCoMDNCk0LjQu9C40L/QvzE1MDMGA1UEAwws0JXRhNC40LzQvtCy\nINCk0LjQu9C40L/QvyDQkNGA0YXQuNC/0L7QstC40YcxJTAjBgkqhkiG9w0BCQEW\nFlVzZXIxNzZAcG9jaHRvY2hrYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCibtSH2YP4oxFVgiAvLdtAZpnVDWNZNgAnCEQwNbPIQpavY3OeoI/a\nNchXgwTn2u9yejOCEu8Q+x++RQDXVeSvPciVIzfDJ5Ex2MPzJySro3iPjT+HCITu\n/sddVv3Lnz5koNzOA5RihTQ+toHsvNgI2/aLITBXVM4JtkQ0ezqNsXDFqVr0Xws/\n3xj33BhhDXDrC24ivnDspYwbjevbrc5/L/mFhkHYX5pCJoxcNd5T8JrVUC1qkBIm\nnFA0C5dMAC6qWlglIG7BAkqc4Z/bu0WxEqsi0353BlnD9A/3k4euY5vmVRn2m/6E\ns89K5XrnqRYap5/o6zkQs64n7HLDQ8F3AgMBAAGgADANBgkqhkiG9w0BAQsFAAOC\nAQEASXlft+61y8TeYhXZQbuLdORjXk4yiI4OAecItHg1GcBiscA2OWObXRalLHlP\nsGc/fp5y82wZ24YxgHbyyRGf1DU374Iz5YqEl9IJ6WPsx9j/BpUo8cNPLaBOID2P\nKUHOMNbmy2bpPAi9AiaRXef9Tz3lIlzjW+oBWDoKtLkVmGDY+aTmwm0ASdqzuc/Q\ndFEgJ1JrZtwjDxwDrtAt+FXbwvadWMo9uhKW9DAaPm9XOte8z/ACoNlQ6G6KGPT3\nYQtk+dIjzeB3po9wZklg19xV17H9WCo+p3K85ANyFjkeePB49DIfwv+04a8kOsaY\nG0ocUXmTIgNeVKyDFtFoUF+qeg==\n\n-----END + CERTIFICATE REQUEST-----' + description: Запрос на создание заявки на выпуск RSA-сертификата + example: + tokenSerialNumber: 00a81050 + pkcs10Content: '-----BEGIN CERTIFICATE REQUEST-----\nMIIC3zCCAccCAQAwgZkxCzAJBgNVBAYTAlJVMRUwEwYDVQQEDAzQldGE0LjQvNC+\n0LIxFTATBgNVBCoMDNCk0LjQu9C40L/QvzE1MDMGA1UEAwws0JXRhNC40LzQvtCy\nINCk0LjQu9C40L/QvyDQkNGA0YXQuNC/0L7QstC40YcxJTAjBgkqhkiG9w0BCQEW\nFlVzZXIxNzZAcG9jaHRvY2hrYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCibtSH2YP4oxFVgiAvLdtAZpnVDWNZNgAnCEQwNbPIQpavY3OeoI/a\nNchXgwTn2u9yejOCEu8Q+x++RQDXVeSvPciVIzfDJ5Ex2MPzJySro3iPjT+HCITu\n/sddVv3Lnz5koNzOA5RihTQ+toHsvNgI2/aLITBXVM4JtkQ0ezqNsXDFqVr0Xws/\n3xj33BhhDXDrC24ivnDspYwbjevbrc5/L/mFhkHYX5pCJoxcNd5T8JrVUC1qkBIm\nnFA0C5dMAC6qWlglIG7BAkqc4Z/bu0WxEqsi0353BlnD9A/3k4euY5vmVRn2m/6E\ns89K5XrnqRYap5/o6zkQs64n7HLDQ8F3AgMBAAGgADANBgkqhkiG9w0BAQsFAAOC\nAQEASXlft+61y8TeYhXZQbuLdORjXk4yiI4OAecItHg1GcBiscA2OWObXRalLHlP\nsGc/fp5y82wZ24YxgHbyyRGf1DU374Iz5YqEl9IJ6WPsx9j/BpUo8cNPLaBOID2P\nKUHOMNbmy2bpPAi9AiaRXef9Tz3lIlzjW+oBWDoKtLkVmGDY+aTmwm0ASdqzuc/Q\ndFEgJ1JrZtwjDxwDrtAt+FXbwvadWMo9uhKW9DAaPm9XOte8z/ACoNlQ6G6KGPT3\nYQtk+dIjzeB3po9wZklg19xV17H9WCo+p3K85ANyFjkeePB49DIfwv+04a8kOsaY\nG0ocUXmTIgNeVKyDFtFoUF+qeg==\n\n-----END + CERTIFICATE REQUEST-----' + ResponesIssueRSACertificate: + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + type: + type: string + description: Тип заявки + enum: + - issueRsaCertificate + - activationRsaCertificate + - currentSignTypeRsa + - currentSignTypeQes + status: + type: string + description: Статус заявки + example: CREATED + creator: + type: string + description: ФИО создателя заявки + example: Ефимов Филипп Архипович + createdDate: + type: string + description: Дата создания заявки + format: date-time + description: Ответ на создание заявки на выпуск RSA-сертификата + example: + creator: Ефимов Филипп Архипович + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: issueRsaCertificate + status: CREATED + RequestPostOperations: + type: object + properties: + requestType: + type: string + description: Тип заявки + enum: + - issueRsaCertificate + - activationRsaCertificate + - currentSignTypeRsa + - switchRsaCertificate + - revocationRsaCertificate + - reissueRsaCertificate + - currentSignTypeQes + description: Запрос отправки на подпись + example: + requestType: issueRsaCertificate + ResponsePostOperations: + type: object + properties: + id: + type: string + description: Идентификатор операции + example: 2629a563-3c82-44a2-a4f5-67b79e44cbea + requestId: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + requestType: + type: string + description: Тип заявки + enum: + - issueRsaCertificate + - activationRsaCertificate + - currentSignTypeRsa + - switchRsaCertificate + - revocationRsaCertificate + - reissueRsaCertificate + - currentSignTypeQes + description: Ответ отправки заявки на подпись + example: + requestType: issueRsaCertificate + requestId: 62550ef50163785f2222707e + id: 2629a563-3c82-44a2-a4f5-67b79e44cbea + RequestPutOperations: + type: object + properties: + code: + type: string + description: Одноразовый код + example: "11111111" + description: Запрос на подписание заявки + example: + code: "11111111" + ResponsePutOperations: + type: object + properties: + id: + type: string + description: Идентификатор операции + example: 2629a563-3c82-44a2-a4f5-67b79e44cbea + isSigned: + type: boolean + description: Признак достаточности подписей под документом + requestId: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + requestType: + type: string + description: Тип заявки + enum: + - issueRsaCertificate + - activationRsaCertificate + - currentSignTypeRsa + - switchRsaCertificate + - revocationRsaCertificate + - reissueRsaCertificate + - currentSignTypeQes + description: Ответ на подписание заявки + example: + isSigned: true + requestType: issueRsaCertificate + requestId: 62550ef50163785f2222707e + id: 2629a563-3c82-44a2-a4f5-67b79e44cbea + RequestData: + type: object + properties: + requestIssueRsaCertificate: + type: array + description: Заявка на выпуск RSA-сертификата + items: + $ref: '#/components/schemas/DataRequestIssueRsaCertificate' + requestActivateRsaCertificate: + type: array + description: Заявка на активацию RSA-сертификата + items: + $ref: '#/components/schemas/DataRequestActivateRsaCertificate' + requestCurrentSignTypeRsa: + type: array + description: Заявка на изменение основного способа + items: + $ref: '#/components/schemas/DataRequestCurrentSignTypeRsa' + requestCurrentSignTypeQes: + type: array + items: + $ref: '#/components/schemas/DataRequestCurrentSignTypeRsa' + requestSwitchRsaCertificate: + type: array + description: Заявка на переключение RSA-сертификата + items: + $ref: '#/components/schemas/DataRequestCurrentSignTypeRsa' + requestRevocationRsaCertificate: + type: array + description: Заявка на отзыв RSA-сертификата + items: + $ref: '#/components/schemas/DataRequestCurrentSignTypeRsa' + requestReissueRsaCertificate: + type: array + description: Заявка на перевыпуск RSA-сертификата + items: + $ref: '#/components/schemas/DataRequestActivateRsaCertificate' + requestEnableSignTypeQes: + type: array + items: + $ref: '#/components/schemas/DataRequestCurrentSignTypeRsa' + description: Данные заявки + example: + requestActivateRsaCertificate: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestSwitchRsaCertificate: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestReissueRsaCertificate: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestCurrentSignTypeQes: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestIssueRsaCertificate: + - createdAt: 2000-01-23T04:56:07.000+00:00 + createdBy: Сафонов Тихон Ерофеевич + id: 62550ef50163785f2222707e + type: issueRsaCertificate + results: + owner: Ефимов Филипп Архипович + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2000-01-23T04:56:07.000+00:00 + executionDate: 2000-01-23T04:56:07.000+00:00 + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2000-01-23T04:56:07.000+00:00 + caRequestId: 220220 + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - createdAt: 2000-01-23T04:56:07.000+00:00 + createdBy: Сафонов Тихон Ерофеевич + id: 62550ef50163785f2222707e + type: issueRsaCertificate + results: + owner: Ефимов Филипп Архипович + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2000-01-23T04:56:07.000+00:00 + executionDate: 2000-01-23T04:56:07.000+00:00 + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2000-01-23T04:56:07.000+00:00 + caRequestId: 220220 + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestCurrentSignTypeRsa: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestRevocationRsaCertificate: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + requestEnableSignTypeQes: + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + - creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + DataRequestIssueRsaCertificate: + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + type: + type: string + description: Тип заявки + enum: + - issueRsaCertificate + status: + type: string + description: Статус заявки + example: FINISHED + createdBy: + type: string + description: ФИО создателя заявки + example: Сафонов Тихон Ерофеевич + createdAt: + type: string + description: Дата создания заявки + format: date-time + finishedDate: + type: string + description: Дата завершения заявки + format: date-time + results: + $ref: '#/components/schemas/ResultsRequestIssueRsaCertificat' + description: Данные заявки на выпуск RSA-сертификата + example: + createdAt: 2000-01-23T04:56:07.000+00:00 + createdBy: Сафонов Тихон Ерофеевич + id: 62550ef50163785f2222707e + type: issueRsaCertificate + results: + owner: Ефимов Филипп Архипович + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2000-01-23T04:56:07.000+00:00 + executionDate: 2000-01-23T04:56:07.000+00:00 + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2000-01-23T04:56:07.000+00:00 + caRequestId: 220220 + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + ResultsRequestIssueRsaCertificat: + type: object + properties: + owner: + type: string + description: Владелец сертфиката + example: Ефимов Филипп Архипович + notAfter: + type: string + description: Дата истечения срока действия сертификата (UTC) + format: date-time + notBefore: + type: string + description: Дата выпуска сертификата в УЦ (UTC) + format: date-time + serialNumber: + type: string + description: Серийный номер сертификата + example: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: + type: string + description: Дата отправки + format: date-time + executionDate: + type: string + description: Дата исполнения + format: date-time + thumbprint: + type: string + description: Отпечаток сертификата + example: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + $ref: '#/components/schemas/Dn' + issuedCertificateId: + type: string + description: Идентификатор сертификата + example: 62552f2457595f1652c4b179 + caRequestId: + type: number + description: Идентификатор запроса на отзыв в УЦ + example: 220220 + description: Результат выполнения заявки на выпуск RSA-сертификата + example: + owner: Ефимов Филипп Архипович + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2000-01-23T04:56:07.000+00:00 + executionDate: 2000-01-23T04:56:07.000+00:00 + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2000-01-23T04:56:07.000+00:00 + caRequestId: 220220 + Dn: + type: object + properties: + firstName: + type: string + description: Имя + example: Филипп + lastName: + type: string + description: Фамилия + example: Ефимов + fullName: + type: string + description: Полное ФИО + example: Ефимов Филипп Архипович + country: + type: string + description: Страна + example: RU + email: + type: string + description: Электронная почта + example: User176@pochtochka.com + description: Данные о владельце сертификата + example: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + DataRequestActivateRsaCertificate: + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + type: + type: string + description: Тип заявки + enum: + - activationRsaCertificate + - reissueRsaCertificate + status: + type: string + description: Статус заявки + example: FINISHED + creator: + type: string + description: ФИО создателя заявки + example: Сафонов Тихон Ерофеевич + createdDate: + type: string + description: Дата создания заявки + format: date-time + finishedDate: + type: string + description: Дата завершения заявки + format: date-time + results: + $ref: '#/components/schemas/ResultsRequestActivateRsaCertificat' + description: Данные заявки на активацию RSA-сертификата/на изменение основного + способа подписи + example: + creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + ResultsRequestActivateRsaCertificat: + type: object + properties: + userSignMethodType: + type: string + description: Тип метода подписания + example: RSA + userSignMethodStatus: + type: string + description: Статус метода подписания + example: ENABLED + description: Результат выполнения заявки на активацию RSA-сертификата + example: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + DataRequestCurrentSignTypeRsa: + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 62550ef50163785f2222707e + type: + type: string + description: Тип заявки + enum: + - currentSignTypeRsa + - switchRsaCertificate + - revocationRsaCertificate + - currentSignTypeQes + - enableQesSignType + status: + type: string + description: Статус заявки + example: FINISHED + creator: + type: string + description: ФИО создателя заявки + example: Сафонов Тихон Ерофеевич + createdDate: + type: string + description: Дата создания заявки + format: date-time + finishedDate: + type: string + description: Дата завершения заявки + format: date-time + description: Данные заявки на выпуск RSA-сертификата + example: + creator: Сафонов Тихон Ерофеевич + createdDate: 2000-01-23T04:56:07.000+00:00 + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2000-01-23T04:56:07.000+00:00 + RSACertificate: + type: object + properties: + content: + type: string + description: Содержимое сертификата + example: MIIFzDCCBICgAwIBAgITYQADXDz/iM0A8B1zSgABAANcPDBBBgkqhkiG9w0BAQow\r\nNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUA\r\nogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UE\r\nCxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENB\r\nIDEwHhcNMjIwNDEyMDczOTI3WhcNMjQwNDEyMDc0OTI3WjCBmTEVMBMGA1UEKgwM\r\n0KTQuNC70LjQv9C/MRUwEwYDVQQEDAzQldGE0LjQvNC+0LIxCzAJBgNVBAYTAlJV\r\nMTUwMwYDVQQDDCzQldGE0LjQvNC+0LIg0KTQuNC70LjQv9C/INCQ0YDRhdC40L/Q\r\nvtCy0LjRhzElMCMGCSqGSIb3DQEJARYWVXNlcjE3NkBwb2NodG9jaGthLmNvbTCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJu1IfZg/ijEVWCIC8t20Bm\r\nmdUNY1k2ACcIRDA1s8hClq9jc56gj9o1yFeDBOfa73J6M4IS7xD7H75FANdV5K89\r\nyJUjN8MnkTHYw/MnJKujeI+NP4cIhO7+x11W/cufPmSg3M4DlGKFND62gey82Ajb\r\n9oshMFdUzgm2RDR7Oo2xcMWpWvRfCz/fGPfcGGENcOsLbiK+cOyljBuN69utzn8v\r\n+YWGQdhfmkImjFw13lPwmtVQLWqQEiacUDQLl0wALqpaWCUgbsECSpzhn9u7RbES\r\nqyLTfncGWcP0D/eTh65jm+ZVGfab/oSzz0rleuepFhqnn+jrORCzrifscsNDwXcC\r\nAwEAAaOCAeAwggHcMB0GA1UdDgQWBBTbfzj1CFqgIOUtAqiQPszkaMdawzAfBgNV\r\nHSMEGDAWgBTJFzMem6mUoJYYS25xTIHb6XP+ZTCBuwYDVR0fBIGzMIGwMIGtoIGq\r\noIGnhjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZh\r\nLUJhbmtfU0NBMS5jcmyGMGh0dHA6Ly92bGt3czY6OTA4MS9kaXN0cnBvaW50L0Fs\r\nZmEtQmFua19TQ0ExLmNybIY4aHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlz\r\ndHJwb2ludC9BbGZhLUJhbmtfU0NBMS5jcmwwgdsGCCsGAQUFBwEBBIHOMIHLMEUG\r\nCCsGAQUFBzAChjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2lu\r\ndC9BbGZhLUJhbmtfU0NBMS5jcnQwPAYIKwYBBQUHMAKGMGh0dHA6Ly92bGt3czY6\r\nOTA4MS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBEBggrBgEFBQcwAoY4\r\naHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZhLUJhbmtf\r\nU0NBMS5jcnQwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqG\r\nSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQA7qvezzVUukOu6PusP9Ulr\r\n801fn7lJlEG4suRmmqWTaOUkkwfoOV+AjyN4K9LtF8JF4BE7ovoz+BAXNl6IIaxB\r\nLup0lnIf2UUXvg8XoAZ9SCNnDdmHI05NrONrRg+7DyCv8FpyudFTkFhmkaMojuUH\r\nZN8V27KlW3Q0ijDrOyn9/rIqAIA5JVbvUfRIMR8DXpZsIkf0HAnZN4Zswn0U5U0K\r\n46Ewva4fWvF7u3638Hkv8u5XNU6E1eaJTWxVM+4J8HdnnTDHSDO27VFh9SxCP8E7\r\ncvQhIhfOXz2qESMSnC2bmlGm863E7fMGxNIpikE2D5LO8Z0KiI0qrhZA7p4tye2c\r\n + certificate: + $ref: '#/components/schemas/DataRSACertificate' + description: RSA-сертификат + example: + certificate: + owner: Ефимов Филипп Архипович + tokenSerialNumber: 00a81050 + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + expireSoon: true + id: 62552f2457595f1652c4b179 + tokenKeyId: "AlboKey_{BBB5EB5D-2B38-488B-B9E2-5E336DDE3DE9}" + actions: + - available: true + type: UPLOAD_ON_TOKEN + - available: true + type: UPLOAD_ON_TOKEN + notBefore: 2000-01-23T04:56:07.000+00:00 + status: CERT_VALID + uploadOnToken: true + content: MIIFzDCCBICgAwIBAgITYQADXDz/iM0A8B1zSgABAANcPDBBBgkqhkiG9w0BAQow\r\nNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUA\r\nogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UE\r\nCxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENB\r\nIDEwHhcNMjIwNDEyMDczOTI3WhcNMjQwNDEyMDc0OTI3WjCBmTEVMBMGA1UEKgwM\r\n0KTQuNC70LjQv9C/MRUwEwYDVQQEDAzQldGE0LjQvNC+0LIxCzAJBgNVBAYTAlJV\r\nMTUwMwYDVQQDDCzQldGE0LjQvNC+0LIg0KTQuNC70LjQv9C/INCQ0YDRhdC40L/Q\r\nvtCy0LjRhzElMCMGCSqGSIb3DQEJARYWVXNlcjE3NkBwb2NodG9jaGthLmNvbTCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJu1IfZg/ijEVWCIC8t20Bm\r\nmdUNY1k2ACcIRDA1s8hClq9jc56gj9o1yFeDBOfa73J6M4IS7xD7H75FANdV5K89\r\nyJUjN8MnkTHYw/MnJKujeI+NP4cIhO7+x11W/cufPmSg3M4DlGKFND62gey82Ajb\r\n9oshMFdUzgm2RDR7Oo2xcMWpWvRfCz/fGPfcGGENcOsLbiK+cOyljBuN69utzn8v\r\n+YWGQdhfmkImjFw13lPwmtVQLWqQEiacUDQLl0wALqpaWCUgbsECSpzhn9u7RbES\r\nqyLTfncGWcP0D/eTh65jm+ZVGfab/oSzz0rleuepFhqnn+jrORCzrifscsNDwXcC\r\nAwEAAaOCAeAwggHcMB0GA1UdDgQWBBTbfzj1CFqgIOUtAqiQPszkaMdawzAfBgNV\r\nHSMEGDAWgBTJFzMem6mUoJYYS25xTIHb6XP+ZTCBuwYDVR0fBIGzMIGwMIGtoIGq\r\noIGnhjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZh\r\nLUJhbmtfU0NBMS5jcmyGMGh0dHA6Ly92bGt3czY6OTA4MS9kaXN0cnBvaW50L0Fs\r\nZmEtQmFua19TQ0ExLmNybIY4aHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlz\r\ndHJwb2ludC9BbGZhLUJhbmtfU0NBMS5jcmwwgdsGCCsGAQUFBwEBBIHOMIHLMEUG\r\nCCsGAQUFBzAChjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2lu\r\ndC9BbGZhLUJhbmtfU0NBMS5jcnQwPAYIKwYBBQUHMAKGMGh0dHA6Ly92bGt3czY6\r\nOTA4MS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBEBggrBgEFBQcwAoY4\r\naHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZhLUJhbmtf\r\nU0NBMS5jcnQwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqG\r\nSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQA7qvezzVUukOu6PusP9Ulr\r\n801fn7lJlEG4suRmmqWTaOUkkwfoOV+AjyN4K9LtF8JF4BE7ovoz+BAXNl6IIaxB\r\nLup0lnIf2UUXvg8XoAZ9SCNnDdmHI05NrONrRg+7DyCv8FpyudFTkFhmkaMojuUH\r\nZN8V27KlW3Q0ijDrOyn9/rIqAIA5JVbvUfRIMR8DXpZsIkf0HAnZN4Zswn0U5U0K\r\n46Ewva4fWvF7u3638Hkv8u5XNU6E1eaJTWxVM+4J8HdnnTDHSDO27VFh9SxCP8E7\r\ncvQhIhfOXz2qESMSnC2bmlGm863E7fMGxNIpikE2D5LO8Z0KiI0qrhZA7p4tye2c\r\n + DataRSACertificate: + type: object + properties: + id: + type: string + description: Идентификатор сертификата + example: 62552f2457595f1652c4b179 + serialNumber: + type: string + description: Серийный номер сертификата + example: 6100035c3cff88cd00f01d734a000100035c3c + tokenKeyId: + type: string + description: Идентификатор закрытого ключа на токене + example: "AlboKey_{BBB5EB5D-2B38-488B-B9E2-5E336DDE3DE9}" + tokenSerialNumber: + type: string + description: Серийный номер токена на который загружен сертификат + example: 00a81050 + status: + type: string + description: Статус сертификата + example: CERT_VALID + notBefore: + type: string + description: Дата начала действия сертификата + format: date-time + notAfter: + type: string + description: Дата завершения действия сертификата + format: date-time + owner: + type: string + description: ФИО владельца сертификата + example: Ефимов Филипп Архипович + uploadOnToken: + type: boolean + description: Признак загрузки сертификата на токен + expireSoon: + type: boolean + description: "Признак необходимости перевыпуска сертификата, по причине\ + \ завершения действия" + actions: + type: array + description: Список всех возможных действий над сертификатом + items: + $ref: '#/components/schemas/ActionsRSACertificate_inner' + description: Данные сертификата + example: + owner: Ефимов Филипп Архипович + tokenSerialNumber: 00a81050 + notAfter: 2000-01-23T04:56:07.000+00:00 + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + expireSoon: true + id: 62552f2457595f1652c4b179 + tokenKeyId: "AlboKey_{BBB5EB5D-2B38-488B-B9E2-5E336DDE3DE9}" + actions: + - available: true + type: UPLOAD_ON_TOKEN + - available: true + type: UPLOAD_ON_TOKEN + notBefore: 2000-01-23T04:56:07.000+00:00 + status: CERT_VALID + uploadOnToken: true + ActionsRSACertificate: + type: array + description: Список всех возможных действий над сертификатом + items: + $ref: '#/components/schemas/ActionsRSACertificate_inner' + SignSettings: + type: object + properties: + currentSignType: + type: string + description: Тип основной подписи + example: rsa-certificates + description: Тип основной подписи + example: + currentSignType: rsa-certificates + RequestReissueRSACertificate: + type: object + properties: + tokenSerialNumber: + type: string + description: Серийный номер USB ключа + example: 00a81050 + pkcs10Content: + type: string + description: Контект PKCS10 + example: '-----BEGIN CERTIFICATE REQUEST-----\nMIIC3zCCAccCAQAwgZkxCzAJBgNVBAYTAlJVMRUwEwYDVQQEDAzQldGE0LjQvNC+\n0LIxFTATBgNVBCoMDNCk0LjQu9C40L/QvzE1MDMGA1UEAwws0JXRhNC40LzQvtCy\nINCk0LjQu9C40L/QvyDQkNGA0YXQuNC/0L7QstC40YcxJTAjBgkqhkiG9w0BCQEW\nFlVzZXIxNzZAcG9jaHRvY2hrYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCibtSH2YP4oxFVgiAvLdtAZpnVDWNZNgAnCEQwNbPIQpavY3OeoI/a\nNchXgwTn2u9yejOCEu8Q+x++RQDXVeSvPciVIzfDJ5Ex2MPzJySro3iPjT+HCITu\n/sddVv3Lnz5koNzOA5RihTQ+toHsvNgI2/aLITBXVM4JtkQ0ezqNsXDFqVr0Xws/\n3xj33BhhDXDrC24ivnDspYwbjevbrc5/L/mFhkHYX5pCJoxcNd5T8JrVUC1qkBIm\nnFA0C5dMAC6qWlglIG7BAkqc4Z/bu0WxEqsi0353BlnD9A/3k4euY5vmVRn2m/6E\ns89K5XrnqRYap5/o6zkQs64n7HLDQ8F3AgMBAAGgADANBgkqhkiG9w0BAQsFAAOC\nAQEASXlft+61y8TeYhXZQbuLdORjXk4yiI4OAecItHg1GcBiscA2OWObXRalLHlP\nsGc/fp5y82wZ24YxgHbyyRGf1DU374Iz5YqEl9IJ6WPsx9j/BpUo8cNPLaBOID2P\nKUHOMNbmy2bpPAi9AiaRXef9Tz3lIlzjW+oBWDoKtLkVmGDY+aTmwm0ASdqzuc/Q\ndFEgJ1JrZtwjDxwDrtAt+FXbwvadWMo9uhKW9DAaPm9XOte8z/ACoNlQ6G6KGPT3\nYQtk+dIjzeB3po9wZklg19xV17H9WCo+p3K85ANyFjkeePB49DIfwv+04a8kOsaY\nG0ocUXmTIgNeVKyDFtFoUF+qeg==\n\n-----END + CERTIFICATE REQUEST-----' + revokeCertificates: + type: array + description: "Список сертификатов, которые необходимо отозвать, включая\ + \ идентификатор сертификата для перевыпуска" + items: + type: string + example: 62552f2457595f1652c4b179 + description: Запрос на создание заявки на выпуск RSA-сертификата + example: + revokeCertificates: + - 62552f2457595f1652c4b179 + - 62552f2457595f1652c4b179 + tokenSerialNumber: 00a81050 + pkcs10Content: '-----BEGIN CERTIFICATE REQUEST-----\nMIIC3zCCAccCAQAwgZkxCzAJBgNVBAYTAlJVMRUwEwYDVQQEDAzQldGE0LjQvNC+\n0LIxFTATBgNVBCoMDNCk0LjQu9C40L/QvzE1MDMGA1UEAwws0JXRhNC40LzQvtCy\nINCk0LjQu9C40L/QvyDQkNGA0YXQuNC/0L7QstC40YcxJTAjBgkqhkiG9w0BCQEW\nFlVzZXIxNzZAcG9jaHRvY2hrYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\nggEKAoIBAQCibtSH2YP4oxFVgiAvLdtAZpnVDWNZNgAnCEQwNbPIQpavY3OeoI/a\nNchXgwTn2u9yejOCEu8Q+x++RQDXVeSvPciVIzfDJ5Ex2MPzJySro3iPjT+HCITu\n/sddVv3Lnz5koNzOA5RihTQ+toHsvNgI2/aLITBXVM4JtkQ0ezqNsXDFqVr0Xws/\n3xj33BhhDXDrC24ivnDspYwbjevbrc5/L/mFhkHYX5pCJoxcNd5T8JrVUC1qkBIm\nnFA0C5dMAC6qWlglIG7BAkqc4Z/bu0WxEqsi0353BlnD9A/3k4euY5vmVRn2m/6E\ns89K5XrnqRYap5/o6zkQs64n7HLDQ8F3AgMBAAGgADANBgkqhkiG9w0BAQsFAAOC\nAQEASXlft+61y8TeYhXZQbuLdORjXk4yiI4OAecItHg1GcBiscA2OWObXRalLHlP\nsGc/fp5y82wZ24YxgHbyyRGf1DU374Iz5YqEl9IJ6WPsx9j/BpUo8cNPLaBOID2P\nKUHOMNbmy2bpPAi9AiaRXef9Tz3lIlzjW+oBWDoKtLkVmGDY+aTmwm0ASdqzuc/Q\ndFEgJ1JrZtwjDxwDrtAt+FXbwvadWMo9uhKW9DAaPm9XOte8z/ACoNlQ6G6KGPT3\nYQtk+dIjzeB3po9wZklg19xV17H9WCo+p3K85ANyFjkeePB49DIfwv+04a8kOsaY\nG0ocUXmTIgNeVKyDFtFoUF+qeg==\n\n-----END + CERTIFICATE REQUEST-----' + EnableQesResponse: + required: + - createdAt + - createdBy + - id + - status + - type + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 63160a37e27edd0c316567a6 + type: + type: string + description: Тип заявки + example: enableQesSignType + status: + type: string + description: Статус заявки + example: CREATED + createdBy: + type: string + description: ФИО создателя заявки + example: Дмитриев Денис Михайлович + createdAt: + type: string + description: Дата создания заявки + format: date-time + example: 2022-09-05T14:39:51.197Z + example: + createdAt: 2022-09-05T14:39:51.197Z + createdBy: Дмитриев Денис Михайлович + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + status: CREATED + SendRequestQes: + required: + - type + type: object + properties: + type: + type: string + description: | + Тип заявки. Возможные значения: + * `enableQesSignType` - заявка на подключение способа подписи КЭП + example: enableQesSignType + example: + type: enableQesSignType + RequestType: + type: string + description: | + Тип заявки. Возможные значения: + * `enableQesSignType` - заявка на подключение способа подписи КЭП + example: enableQesSignType + SendRequestQesResponse: + required: + - content + - id + - type + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 63160a37e27edd0c316567a6 + type: + type: string + description: | + Тип заявки. Возможные значения: + * `enableQesSignType` - заявка на подключение способа подписи КЭП + example: enableQesSignType + content: + type: string + description: Документ на подпись в формате base64 + example: + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + content: content + SignRequestQes: + required: + - signature + - type + type: object + properties: + type: + type: string + description: | + Тип заявки. Возможные значения: + * `enableQesSignType` - заявка на подключение способа подписи КЭП + example: enableQesSignType + signature: + minLength: 1 + type: string + description: "Значение электронной подписи, закодированное в base64" + example: + signature: signature + type: enableQesSignType + SignRequestQesResponse: + required: + - id + - isSigned + - type + type: object + properties: + id: + type: string + description: Идентификатор заявки + example: 63160a37e27edd0c316567a6 + type: + type: string + description: | + Тип заявки. Возможные значения: + * `enableQesSignType` - заявка на подключение способа подписи КЭП + example: enableQesSignType + isSigned: + type: boolean + description: Признак достаточности подписей + example: true + example: + isSigned: true + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + DownloadPoaRequest: + required: + - confidantInn + - issuerInn + - poaNumber + type: object + properties: + poaNumber: + type: string + description: Номер доверенности + example: 8e08423a-bcc0-4fba-a791-9825cb1a7cb3 + issuerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН доверителя + example: "7727464030" + confidantInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН доверенного лица + example: "420548688683" + description: Данные для регистрации МЧД + example: + issuerInn: "7727464030" + confidantInn: "420548688683" + poaNumber: 8e08423a-bcc0-4fba-a791-9825cb1a7cb3 + DownloadPoaResponse: + required: + - id + type: object + properties: + id: + type: string + description: Идентификатор запроса в системе МЧД + example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + example: + id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + GetDownloadStatus: + required: + - status + type: object + properties: + status: + type: string + description: | + Статус машиночитаемой доверенности (МЧД). Принимает возможные значения: + * `COMPLETE` - Операция завершена; + * `PENDING` - Операция выполняется. Идет запрос данных с узла ФНС; + * `FAILED` - Ошибка; + * `TIMEOUT` - Превышен лимит ожидания + example: COMPLETE + enum: + - COMPLETE + - PENDING + - FAILED + - TIMEOUT + description: Объект предоставляет статус скачивания полной версии машиночитаемой + доверенности + example: + status: COMPLETE + Payment: + required: + - amount + - date + - externalId + - operationCode + - payeeAccount + - payeeBankBic + - payeeName + - payerAccount + - payerBankBic + - payerBankCorrAccount + - payerInn + - payerName + - priority + - purpose + type: object + properties: + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 1.01 + bankComment: + type: string + description: Банковский комментарий к статусу документа + example: "" + bankStatus: + type: string + description: Статус документа + example: CREATED + crucialFieldsHash: + type: string + description: Hash от ключевых полей документа + example: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + date: + type: string + description: Дата составления документа + format: date + example: 2022-10-11 + deliveryKind: + type: string + description: Вид платежа + example: электронно + departmentalInfo: + $ref: '#/components/schemas/DepartmentalInfo_1' + digestSignatures: + type: array + items: + $ref: '#/components/schemas/Signature' + externalId: + type: string + description: "Идентификатор документа, присвоенный партнером (UUID)" + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + incomeTypeCode: + pattern: "^\\d{1}$" + type: string + description: Код вида дохода получателей выплаты по 229-ФЗ + example: "2" + number: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер документа + example: "1" + operationCode: + type: string + description: "Код операции: 01" + example: "01" + enum: + - "01" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + payeeBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка получателя платежа + example: "30101810800000000745" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет плательщика + example: "40702810102300000001" + payerBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка плательщика + example: "044525593" + payerBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка плательщика + example: "30101810200000000593" + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "0453438040" + payerKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП плательщика + example: "046773311" + payerName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование плательщика + example: Общество с ограниченной ответственностью "Клиент" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очередность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата заказа №1. НДС не облагается + urgencyCode: + $ref: '#/components/schemas/UrgencyCode' + vat: + $ref: '#/components/schemas/Vat' + description: Данные рублёвого платёжного поручения + example: + date: 2022-10-11T00:00:00.000+00:00 + payerBankCorrAccount: "30101810200000000593" + digestSignatures: + - base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + - base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + purpose: Оплата заказа №1. НДС не облагается + bankComment: "" + operationCode: "01" + deliveryKind: электронно + crucialFieldsHash: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerName: Общество с ограниченной ответственностью "Клиент" + payeeBankCorrAccount: "30101810800000000745" + amount: 1.01 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2022-05-25 + uip: "0" + paymentKind110: "0" + payerKpp: "046773311" + vat: + rate: "0" + type: NO_VAT + externalId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + urgencyCode: NORMAL + payerInn: "0453438040" + priority: "5" + payerAccount: "40702810102300000001" + bankStatus: CREATED + payeeBankBic: "040173745" + payerBankBic: "044525593" + incomeTypeCode: "2" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + DepartmentalInfo_1: + type: object + properties: + uip: + maxLength: 25 + type: string + description: Уникальный идентификатор платежа/начисления + example: "0" + drawerStatus101: + pattern: "^\\d{2}$" + type: string + description: Показатель статуса налогоплательщика + example: "01" + kbk: + pattern: "^(([0]{1})|(\\d{20}))$" + type: string + description: Код бюджетной классификации + example: "18210102010011000110" + oktmo: + pattern: "^(([0]{1})|(\\d{8}))$" + type: string + description: Код OKTMO + example: "45902000" + reasonCode106: + maxLength: 2 + type: string + description: Показатель основания платежа + example: ТП + taxPeriod107: + maxLength: 10 + type: string + description: Налоговый период или код таможенного органа + example: МС.02.2022 + docNumber108: + maxLength: 15 + type: string + description: Номер налогового документа + example: "000000000000001" + docDate109: + pattern: "^((\\d{4}-\\d{2}-\\d{2})|([0]{1,2}))$" + type: string + description: Дата налогового документа в формате YYYY-MM-DD + example: 2022-05-25 + paymentKind110: + maxLength: 2 + type: string + description: Тип налогового платежа + example: "0" + description: "Реквизиты налогового, таможенного или иного бюджетного платежа" + example: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2022-05-25 + uip: "0" + paymentKind110: "0" + Signature: + required: + - base64Encoded + - certificateUuid + type: object + properties: + base64Encoded: + minLength: 1 + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: + minLength: 1 + type: string + description: "Идентификатор сертификата, использованного при создании ЭП" + example: 61000366d11e143acbc03a56d70001000366d1 + description: Электронные подписи по дайджесту документа + example: + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + UrgencyCode: + type: string + description: | + Код срочности: + * `OFFHOURS` - Продлённый операционный день; + * `BESP` - Срочный платёж; + * `NORMAL` - Стандартный операционный день + example: NORMAL + enum: + - OFFHOURS + - BESP + - NORMAL + Vat: + required: + - type + type: object + properties: + rate: + type: string + description: Ставка НДС + example: "0" + type: + type: string + description: | + Способ расчета НДС. Возможные значения: + * `NO_VAT` - Не облагается НДС; + * `INCLUDED` - НДС включен в сумму платежа; + * `ONTOP` - НДС добавляется к сумме платежа; + * `MANUAL` - Ручной ввод НДС; + * `AGENT` - НДС исчисляется налоговым агентом + example: NO_VAT + enum: + - INCLUDED + - NO_VAT + - MANUAL + - ONTOP + - AGENT + description: Данные НДС + example: + rate: "0" + type: NO_VAT + ErrorConflict: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: conflict + error_description: + type: string + description: Сообщение об ошибке + example: Request could not be processed because of conflict in the request + description: Конфликт + PaymentDocState: + type: object + properties: + bankStatus: + type: string + description: Статус документа + example: ACCEPTED + bankComment: + type: string + description: Банковский комментарий к статусу документа + example: Проверяем реквизиты платежа. После успешной проверки платёж отправим + в течение банковского дня + crucialFieldsHash: + type: string + description: Hash от ключевых полей документа + example: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + description: Статус платёжного документа + example: + bankStatus: ACCEPTED + bankComment: Проверяем реквизиты платежа. После успешной проверки платёж отправим + в течение банковского дня + crucialFieldsHash: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + PatchPaymentStateRequest: + required: + - bankStatus + type: object + properties: + bankStatus: + type: string + description: | + Статус документа. Возможные значения: + * `PARTSIGNED` - Отправлен на подпись или частично подписан + example: PARTSIGNED + enum: + - PARTSIGNED + example: + bankStatus: PARTSIGNED + PaymentPrintForm: + type: object + properties: + fileName: + type: string + description: Имя файла + example: Платежное_поручение_№657073_11.10.2022.pdf + content: + type: string + description: Содержимое файла + example: JVBERi0xLjUKJeLjz9MKMyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDIwMDA...PgpzdGFydHhyZWYKMTE4MDkKJSVFT0YK + description: Печатная форма документа + example: + fileName: Платежное_поручение_№657073_11.10.2022.pdf + content: JVBERi0xLjUKJeLjz9MKMyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDIwMDA...PgpzdGFydHhyZWYKMTE4MDkKJSVFT0YK + Status: + type: string + description: Статус обработки документа + example: CREATED + enum: + - CREATED + - SIGNED + PaymentsCountResponse: + required: + - count + type: object + properties: + count: + type: integer + description: Количество платежей + format: int64 + example: 100 + example: + count: 100 + InvoiceRequest: + required: + - amount + - date + - externalId + - payeeAccount + - purpose + type: object + properties: + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 1.01 + date: + type: string + description: Дата составления документа в формате YYYY-MM-DD + format: date + example: 2018-12-31 + deliveryKind: + type: string + description: Вид платежа + example: электронно + expirationDate: + type: string + description: Дата истечения заказа + format: date-time + example: 2022-09-12T19:15:51+03:00 + externalId: + type: string + description: "Идентификатор документа, присвоенный партнером (UUID)" + format: uuid + example: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + operationCode: + type: string + description: | + Код операции. Возможные значения: + * `01` - Платёжное поручение + enum: + - "01" + orderNumber: + type: string + description: Номер заказа + example: "1" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeOrgIdHash: + type: string + description: Идентификатор получателя платежа + example: bca96ae8b26184217fcf75f51347bd7bd5031ea6605c434c49f85378e9509732 + paymentNumber: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер платёжного поручения + example: "1" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очередность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата заказа №1. НДС не облагается + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_1' + vat: + $ref: '#/components/schemas/Vat_1' + example: + date: 2018-12-31T00:00:00.000+00:00 + amount: 1.01 + orderNumber: "1" + purpose: Оплата заказа №1. НДС не облагается + operationCode: "01" + vat: + rate: "0" + type: NO_VAT + deliveryKind: электронно + externalId: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + urgencyCode: NORMAL + priority: "5" + payeeOrgIdHash: bca96ae8b26184217fcf75f51347bd7bd5031ea6605c434c49f85378e9509732 + payeeAccount: "40702810564564564531" + paymentNumber: "1" + expirationDate: 2022-09-12T19:15:51+03:00 + UrgencyCode_1: + type: string + description: | + Код срочности. Возможные значения: + * `NORMAL` - Стандартный операционный день; + * `OFFHOURS` - Продлённый операционный день; + * `BESP` - Срочный платёж + example: NORMAL + enum: + - OFFHOURS + - BESP + - NORMAL + Vat_1: + required: + - type + type: object + properties: + rate: + type: string + description: Ставка НДС + example: "0" + type: + type: string + description: | + Способ расчета НДС. Возможные значения: + * `NO_VAT` - Не облагается НДС; + * `INCLUDED` - НДС включен в сумму платежа; + * `ONTOP` - НДС добавляется к сумме платежа; + * `MANUAL` - Ручной ввод НДС; + * `AGENT` - НДС исчисляется налоговым агентом. + example: NO_VAT + enum: + - INCLUDED + - NO_VAT + - MANUAL + - ONTOP + - AGENT + description: Данные НДС + nullable: true + example: + rate: "0" + type: NO_VAT + InvoiceResponse: + required: + - amount + - date + - externalId + - operationCode + - payeeAccount + - payeeBankBic + - payeeName + - priority + - purpose + type: object + properties: + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 1.01 + bankComment: + type: string + description: Банковский комментарий к статусу документа + bankStatus: + type: string + description: Статус документа + example: CREATED + crucialFieldsHash: + type: string + description: Hash от ключевых полей документа + example: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + date: + type: string + description: Дата составления документа в формате YYYY-MM-DD + format: date + example: 2018-12-31 + deliveryKind: + type: string + description: "Вид платежа: электронно" + example: электронно + externalId: + type: string + description: "Идентификатор документа, присвоенный партнером (UUID)" + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + incomeTypeCode: + pattern: "^\\d{1}$" + type: string + description: Код вида дохода получателей выплаты по 229-ФЗ + number: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер документа + example: "1" + operationCode: + type: string + description: "Код операции: 01" + example: "01" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + payeeBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка получателя платежа + example: "30101810200000000593" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт плательщика + example: "40702810600010800068" + payerBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка плательщика + example: "044525225" + payerBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка плательщика + example: "30101810400000000225" + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "7736576798" + payerKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП плательщика + example: "772201001" + payerName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование плательщика + example: Общество с ограниченной ответственностью "Клиент" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очередность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата заказа №1. НДС не облагается + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_1' + vat: + $ref: '#/components/schemas/Vat_1' + description: Данные рублёвого платёжного поручения + example: + date: 2018-12-31T00:00:00.000+00:00 + payerBankCorrAccount: "30101810400000000225" + purpose: Оплата заказа №1. НДС не облагается + bankComment: bankComment + operationCode: "01" + deliveryKind: электронно + crucialFieldsHash: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerName: Общество с ограниченной ответственностью "Клиент" + payeeBankCorrAccount: "30101810200000000593" + amount: 1.01 + payerKpp: "772201001" + vat: + rate: "0" + type: NO_VAT + externalId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + urgencyCode: NORMAL + payerInn: "7736576798" + priority: "5" + payerAccount: "40702810600010800068" + bankStatus: CREATED + payeeBankBic: "040173745" + payerBankBic: "044525225" + incomeTypeCode: incomeTypeCode + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + InvoiceBudgetRequest: + required: + - amount + - date + - departmentalInfo + - externalId + - payeeAccount + - payeeBankBic + - payeeInn + - payeeKpp + - payeeName + - purpose + type: object + properties: + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 100 + date: + type: string + description: Дата составления документа в формате YYYY-MM-DD + format: date + example: 2022-04-01 + deliveryKind: + type: string + description: Вид платежа + example: электронно + departmentalInfo: + $ref: '#/components/schemas/InvoiceDepartmentalInfo' + externalId: + type: string + description: "Идентификатор документа, присвоенный партнером (UUID)" + format: uuid + example: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + operationCode: + type: string + description: | + Код операции. Возможные значения: + * `01` - Платёжное поручение + enum: + - "01" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + payeeBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчёт банка получателя платежа + example: "30101810800000000745" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП плательщика + example: "772201001" + paymentNumber: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер платёжного поручения + example: "1" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очерёдность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_1' + example: + date: 2022-04-01T00:00:00.000+00:00 + amount: 100 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2022-03-25 + uip: "0" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + operationCode: "01" + payerKpp: "772201001" + deliveryKind: электронно + externalId: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + urgencyCode: NORMAL + priority: "5" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeBankBic: "040173745" + payeeInn: "7723870785" + payeeBankCorrAccount: "30101810800000000745" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + paymentNumber: "1" + InvoiceDepartmentalInfo: + required: + - docDate109 + - docNumber108 + - drawerStatus101 + - kbk + - oktmo + - reasonCode106 + - taxPeriod107 + - uip + type: object + properties: + uip: + maxLength: 25 + type: string + description: Уникальный идентификатор платежа/начисления + example: "0" + drawerStatus101: + pattern: "^\\d{2}$" + type: string + description: Показатель статуса налогоплательщика + example: "01" + kbk: + pattern: "^(([0]{1})|(\\d{20}))$" + type: string + description: Код бюджетной классификации + example: "18210102010011000110" + oktmo: + pattern: "^(([0]{1})|(\\d{8}))$" + type: string + description: Код OKTMO + example: "45902000" + reasonCode106: + maxLength: 2 + type: string + description: Показатель основания платежа + example: ТП + taxPeriod107: + pattern: "^(0|[0-9]{8}|([0-9]{2}|МС|КВ|ПЛ|ГД).[0-9]{2}.[0-9]{4})$" + type: string + description: Налоговый период или код таможенного органа + example: МС.02.2022 + docNumber108: + maxLength: 15 + type: string + description: Номер налогового документа + example: "000000000000001" + docDate109: + pattern: "^((\\d{4}-\\d{2}-\\d{2})|([0]{1,2}))$" + type: string + description: Дата налогового документа в формате YYYY-MM-DD + example: 2022-03-25 + description: "Реквизиты налогового, таможенного или иного бюджетного платежа" + example: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2022-03-25 + uip: "0" + InvoiceBudgetResponse: + required: + - amount + - date + - departmentalInfo + - externalId + - operationCode + - payeeAccount + - payeeBankBic + - payeeInn + - payeeName + - priority + - purpose + type: object + properties: + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 100 + bankComment: + type: string + description: Банковский комментарий к статусу документа + bankStatus: + type: string + description: Статус документа + example: CREATED + crucialFieldsHash: + type: string + description: Hash от ключевых полей документа + example: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + date: + type: string + description: Дата составления документа в формате YYYY-MM-DD + format: date + example: 2022-04-01 + deliveryKind: + type: string + description: Вид платежа + example: электронно + departmentalInfo: + $ref: '#/components/schemas/InvoiceDepartmentalInfo' + externalId: + type: string + description: "Идентификатор документа, присвоенный партнером (UUID)" + format: uuid + example: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + number: + type: string + description: Номер документа + example: "1" + operationCode: + type: string + description: | + Код операции. Возможные значения: + * `01` - Платёжное поручение + enum: + - "01" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + payeeBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчёт банка получателя платежа + example: "30101810800000000745" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП плательщика + example: "772201001" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очерёдность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_1' + example: + date: 2022-04-01T00:00:00.000+00:00 + amount: 100 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2022-03-25 + uip: "0" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + bankComment: bankComment + operationCode: "01" + payerKpp: "772201001" + deliveryKind: электронно + externalId: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + urgencyCode: NORMAL + crucialFieldsHash: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + priority: "5" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + bankStatus: CREATED + payeeBankBic: "040173745" + payeeInn: "7723870785" + payeeBankCorrAccount: "30101810800000000745" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + RegistryPaymentsRequest: + required: + - payments + - urgencyCode + type: object + properties: + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_2' + description: + maxLength: 210 + minLength: 1 + type: string + description: Описание реестра + example: Описание реестра + payments: + type: array + items: + $ref: '#/components/schemas/RegistryPayment' + description: Данные реестра платежей + example: + payments: + - date: 2023-12-31T00:00:00.000+00:00 + payerBankCorrAccount: "30101810200000000593" + amount: 1.01 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: ГД.00.2021 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2021-12-14 + uip: "0" + paymentKind110: "0" + purpose: Оплата заказа №1. НДС не облагается + payerKpp: "772201001" + deliveryKind: электронно + payerInn: "7736576798" + priority: "5" + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerBankBic: "044525593" + payeeBankBic: "040173745" + incomeTypeCode: "2" + payerName: Общество с ограниченной ответственностью "Клиент" + payeeInn: "7723870785" + payeeBankCorrAccount: "30101810800000000745" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + - date: 2023-12-31T00:00:00.000+00:00 + payerBankCorrAccount: "30101810200000000593" + amount: 1.01 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: ГД.00.2021 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2021-12-14 + uip: "0" + paymentKind110: "0" + purpose: Оплата заказа №1. НДС не облагается + payerKpp: "772201001" + deliveryKind: электронно + payerInn: "7736576798" + priority: "5" + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerBankBic: "044525593" + payeeBankBic: "040173745" + incomeTypeCode: "2" + payerName: Общество с ограниченной ответственностью "Клиент" + payeeInn: "7723870785" + payeeBankCorrAccount: "30101810800000000745" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + urgencyCode: NORMAL + description: Описание реестра + UrgencyCode_2: + type: string + description: | + Срочность платежей в реестре. Возможные значения: + * `OFFHOURS` - Продлённый операционный день; + * `BESP` - Срочный платёж; + * `NORMAL` - Стандартный операционный день + example: NORMAL + enum: + - OFFHOURS + - BESP + - NORMAL + RegistryPayment: + required: + - amount + - date + - payeeAccount + - payeeBankBic + - payeeInn + - payeeName + - payerAccount + - payerInn + - purpose + type: object + properties: + number: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер документа + example: "1" + date: + type: string + description: Дата составления документа + format: date + example: 2023-12-31 + deliveryKind: + type: string + description: Вид платежа + example: электронно + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 1.01 + payerName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование плательщика + example: Общество с ограниченной ответственностью "Клиент" + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "7736576798" + payerKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП плательщика + example: "772201001" + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт плательщика + example: "40702810102300000001" + payerBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка плательщика + example: "044525593" + payerBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка плательщика + example: "30101810200000000593" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + payeeBankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корсчет банка получателя платежа + example: "30101810800000000745" + departmentalInfo: + $ref: '#/components/schemas/DepartmentalInfo_2' + incomeTypeCode: + pattern: "^\\d{1}$" + type: string + description: Код вида дохода получателей выплаты по 229-ФЗ + example: "2" + priority: + pattern: "^[1-5]{1}$" + type: string + description: Очерёдность платежа + example: "5" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата заказа №1. НДС не облагается + description: Данные рублёвого платёжного поручения + example: + date: 2023-12-31T00:00:00.000+00:00 + payerBankCorrAccount: "30101810200000000593" + amount: 1.01 + departmentalInfo: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: ГД.00.2021 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2021-12-14 + uip: "0" + paymentKind110: "0" + purpose: Оплата заказа №1. НДС не облагается + payerKpp: "772201001" + deliveryKind: электронно + payerInn: "7736576798" + priority: "5" + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerBankBic: "044525593" + payeeBankBic: "040173745" + incomeTypeCode: "2" + payerName: Общество с ограниченной ответственностью "Клиент" + payeeInn: "7723870785" + payeeBankCorrAccount: "30101810800000000745" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + DepartmentalInfo_2: + type: object + properties: + uip: + maxLength: 25 + type: string + description: Уникальный идентификатор платежа/начисления + example: "0" + drawerStatus101: + pattern: "^\\d{2}$" + type: string + description: Показатель статуса налогоплательщика + example: "01" + kbk: + pattern: "^(([0]{1})|(\\d{20}))$" + type: string + description: Код бюджетной классификации + example: "18210102010011000110" + oktmo: + pattern: "^(([0]{1})|(\\d{8}))$" + type: string + description: Код OKTMO + example: "45902000" + reasonCode106: + maxLength: 2 + type: string + description: Показатель основания платежа + example: ТП + taxPeriod107: + maxLength: 10 + type: string + description: Налоговый период или код таможенного органа + example: ГД.00.2021 + docNumber108: + maxLength: 15 + type: string + description: Номер налогового документа + example: "000000000000001" + docDate109: + pattern: "^((\\d{4}-\\d{2}-\\d{2})|([0]{1,2}))$" + type: string + description: Дата налогового документа в формате YYYY-MM-DD + example: 2021-12-14 + paymentKind110: + maxLength: 2 + type: string + description: Код выплат + example: "0" + description: "Реквизиты налогового, таможенного или иного бюджетного платежа" + example: + drawerStatus101: "01" + oktmo: "45902000" + kbk: "18210102010011000110" + taxPeriod107: ГД.00.2021 + docNumber108: "000000000000001" + reasonCode106: ТП + docDate109: 2021-12-14 + uip: "0" + paymentKind110: "0" + RegistryPaymentsResponse: + required: + - registryId + type: object + properties: + registryId: + type: string + description: Идентификатор реестра + example: U102702240001208 + description: + type: string + description: Описание реестра + example: Описание реестра + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт списания + example: "40702810102300000001" + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_2' + paymentsCount: + type: integer + description: Количество платежей реестра + example: 2 + totalAmount: + type: number + description: Общая сумма платежей в реестре + example: 100 + description: Успешный ответ + example: + payerAccount: "40702810102300000001" + totalAmount: 100 + paymentsCount: 2 + registryId: U102702240001208 + description: Описание реестра + urgencyCode: NORMAL + Registry: + type: object + properties: + status: + type: string + description: | + Статус реестра платежей. Принимает возможные значения: + * `UPLOADING` - Загружается; + * `UPLOADED` - Черновик; + * `ON_SIGNING` - На подписании; + * `SIGNED` - Подписан; + * `PROCESSING` - На обработке; + * `DONE` - Исполнен; + * `PARTIALLY_DONE` - Исполнен частично; + * `UPLOAD_ERROR` - Ошибка загрузки; + * `ERROR` - Отклонён банком; + * `DELETED` - Удалён; + * `URGENCY_CHANGE` - Вносим изменения; + * `EDIT_PAYMENTS` - Промежуточный статус во время копирования платежей в реестрах + example: UPLOADED + enum: + - UPLOADING + - UPLOADED + - ON_SIGNING + - SIGNED + - PROCESSING + - DONE + - PARTIALLY_DONE + - UPLOAD_ERROR + - ERROR + - DELETED + - URGENCY_CHANGE + - EDIT_PAYMENTS + description: + type: string + description: Описание реестра + example: Описание реестра + payerName: + type: string + description: Полное наименование плательщика + example: Общество с ограниченной ответственностью "Клиент" + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт списания + example: "40702810102300000001" + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_2' + registryActualState: + $ref: '#/components/schemas/RegistryState' + states: + type: array + items: + $ref: '#/components/schemas/PaymentState' + isValidForSign: + type: boolean + description: Признак готовности реестра к подписанию + description: Данные реестра + example: + payerAccount: "40702810102300000001" + isValidForSign: true + description: Описание реестра + payerName: Общество с ограниченной ответственностью "Клиент" + urgencyCode: NORMAL + registryActualState: + totalAmount: 7484.23 + paymentsCount: 9 + status: UPLOADED + states: + - amount: 7154.07 + count: 3 + status: DRAFT + - amount: 7154.07 + count: 3 + status: DRAFT + RegistryState: + type: object + properties: + paymentsCount: + type: integer + description: Текущее количество платежей в реестре + example: 9 + totalAmount: + type: number + description: Текущая сумма платежей в реестре + example: 7484.23 + example: + totalAmount: 7484.23 + paymentsCount: 9 + PaymentState: + required: + - amount + - count + - status + type: object + properties: + count: + type: integer + description: Количество платежей в указанном статусе + example: 3 + amount: + type: number + description: Сумма платежей в указанном статусе + example: 7154.07 + status: + $ref: '#/components/schemas/PaymentStatus' + example: + amount: 7154.07 + count: 3 + status: DRAFT + PaymentStatus: + type: string + description: | + Статус платежа. Принимает возможные значения: + * `DRAFT` - Черновик; + * `ON_SIGNING` - На подпись; + * `TO_BE_SEND` - К отправке; + * `PROCESSING` - На исполнении; + * `DONE` - Исполнен; + * `REJECTED` - Не исполнен; + * `DECLINED` - Отклонён; + * `DELETED` - Удалён; + * `WITH_ERRORS` - С ошибками + example: DRAFT + enum: + - DRAFT + - ON_SIGNING + - TO_BE_SEND + - PROCESSING + - DONE + - REJECTED + - DECLINED + - DELETED + - WITH_ERRORS + UpdateRegistryStatusRequest: + required: + - status + type: object + properties: + status: + type: string + description: | + Статус реестра платежей. Принимает возможные значения: + * `ON_SIGNING` - на подписании; + * `PROCESSING` - на обработке + example: ON_SIGNING + example: + status: ON_SIGNING + RegistryWithContent: + required: + - payerAccount + - status + - urgencyCode + type: object + properties: + status: + type: string + description: | + Статус реестра платежей. Принимает возможные значения: + * `ON_SIGNING` - На подписании; + * `PROCESSING` - На обработке + example: ON_SIGNING + description: + type: string + description: Описание реестра + example: Описание реестра + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт списания + example: "40702810102300000001" + urgencyCode: + $ref: '#/components/schemas/UrgencyCode_2' + content: + type: string + description: Содержимое документа в формате base64 + example: YW1vdW50PTEwMC4wMApkYXRlPTIwMTgtMDUtMzEKZGVwYXJ0bWVudGFsSW5mby...NOdW1iZXIx= + description: Данные реестра с контентом для подписи + example: + payerAccount: "40702810102300000001" + description: Описание реестра + urgencyCode: NORMAL + content: YW1vdW50PTEwMC4wMApkYXRlPTIwMTgtMDUtMzEKZGVwYXJ0bWVudGFsSW5mby...NOdW1iZXIx= + status: ON_SIGNING + GetRegistryPaymentsResponse: + required: + - payments + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + payments: + type: array + items: + $ref: '#/components/schemas/RegistryPaymentStatus' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + payments: + - date: 2023-12-31T00:00:00.000+00:00 + amount: 1.01 + purpose: Оплата заказа №1. НДС не облагается + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeBankBic: "040173745" + payeeInn: "7723870785" + id: U031308240002351 + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + status: DRAFT + info: Сумма платежа должна состоять из цифр и быть больше 0 + - date: 2023-12-31T00:00:00.000+00:00 + amount: 1.01 + purpose: Оплата заказа №1. НДС не облагается + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeBankBic: "040173745" + payeeInn: "7723870785" + id: U031308240002351 + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + status: DRAFT + info: Сумма платежа должна состоять из цифр и быть больше 0 + Pagination_1: + type: object + properties: + limit: + minimum: 1 + type: integer + description: Количество элементов + example: 10 + offset: + minimum: 0 + type: integer + description: Смещение в результатах поиска + example: 0 + totalCount: + type: integer + description: "Количество элементов, удовлетворяющих запросу" + example: 1 + description: Параметры пагинации + example: + offset: 0 + limit: 10 + totalCount: 1 + RegistryPaymentStatus: + required: + - amount + - date + - payeeAccount + - payeeBankBic + - payeeInn + - payeeName + - payerAccount + - purpose + type: object + properties: + id: + type: string + description: Идентификатор платежа + example: U031308240002351 + number: + pattern: "^(?!0*$)\\d{1,6}$" + type: string + description: Номер документа + example: "1" + status: + $ref: '#/components/schemas/PaymentStatus' + info: + type: string + description: Информационное сообщение для пользователя + example: Сумма платежа должна состоять из цифр и быть больше 0 + date: + type: string + description: Дата составления документа + format: date + example: 2023-12-31 + amount: + minimum: 0 + exclusiveMinimum: true + type: number + description: Сумма платежа + example: 1.01 + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет плательщика + example: "40702810102300000001" + payeeName: + maxLength: 160 + minLength: 1 + type: string + description: Полное наименование получателя платежа + example: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН получателя платежа + example: "7723870785" + payeeKpp: + pattern: "^(([0]{1})|(\\d{4}[A-Z0-9]{2}\\d{3}))$" + type: string + description: КПП получателя платежа + example: "553453453" + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счёт получателя платежа + example: "40702810564564564531" + payeeBankBic: + pattern: "^\\d{9}$" + type: string + description: БИК банка получателя платежа + example: "040173745" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата заказа №1. НДС не облагается + description: Данные рублёвого платёжного поручения + example: + date: 2023-12-31T00:00:00.000+00:00 + amount: 1.01 + purpose: Оплата заказа №1. НДС не облагается + payerAccount: "40702810102300000001" + number: "1" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeBankBic: "040173745" + payeeInn: "7723870785" + id: U031308240002351 + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + status: DRAFT + info: Сумма платежа должна состоять из цифр и быть больше 0 + RegistrySignRequest: + required: + - digestSignatures + type: object + properties: + digestSignatures: + type: array + items: + $ref: '#/components/schemas/Signature_1' + example: + digestSignatures: + - signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + - signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + Signature_1: + required: + - base64Encoded + - signatureType + type: object + properties: + base64Encoded: + minLength: 1 + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: + minLength: 1 + type: string + description: "Идентификатор сертификата, использованного при создании ЭП" + example: 61000366d11e143acbc03a56d70001000366d1 + signatureType: + type: string + description: | + Тип электронной подписи. Возможные значения: + * `QES` - квалифицированная электронная подпись (КЭП); + * `RSA` - подписание с помощью RSA-сертификата + example: RSA + enum: + - QES + - RSA + description: Электронные подписи по дайджесту документа + example: + signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + RegistrySignResponse: + required: + - signatureId + type: object + properties: + signatureId: + type: string + description: Идентификатор запроса на подписание + example: 0937b8b1-b226-45f3-b93e-7ba9008db79a + example: + signatureId: 0937b8b1-b226-45f3-b93e-7ba9008db79a + GetRegistrySignResponse: + required: + - status + type: object + properties: + status: + type: string + description: | + Статус реестра платежей. Принимает возможные значения: + * `ACCEPTED` - Запрос принят и поставлен в очередь на обработку; + * `IN_PROGRESS` - Запрос находится в обработке; + * `PARTIALLY_SIGNED` - Часть подписей успешно наложена, либо переданной(-ых) подписи(-ей) недостаточно; + * `SIGNED` - Реестр платежей успешно подписан; + * `ERROR` - Произошла ошибка при обработке запроса + example: PARTIALLY_SIGNED + enum: + - ACCEPTED + - IN_PROGRESS + - PARTIALLY_SIGNED + - SIGNED + - ERROR + error: + $ref: '#/components/schemas/UnrelatedError' + digestSignatures: + type: array + items: + $ref: '#/components/schemas/SignatureResponse' + example: + digestSignatures: + - signatureType: RSA + errorMessage: errorMessage + errorCode: errorCode + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + status: SIGNED + - signatureType: RSA + errorMessage: errorMessage + errorCode: errorCode + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + status: SIGNED + error: + code: code + message: message + status: PARTIALLY_SIGNED + UnrelatedError: + type: object + properties: + code: + type: string + description: Код ошибки + message: + type: string + description: Сообщение об ошибке + example: + code: code + message: message + SignatureResponse: + required: + - signatureType + - status + type: object + properties: + certificateUuid: + type: string + description: "Идентификатор сертификата, использованного при создании ЭП" + example: 61000366d11e143acbc03a56d70001000366d1 + signatureType: + type: string + description: | + Тип электронной подписи. Принимает возможные значения: + * `QES` - квалифицированная электронная подпись (КЭП); + * `RSA` - подписание с помощью RSA-сертификата + example: RSA + enum: + - QES + - RSA + status: + type: string + description: | + Статус подписания. Принимает возможные значения: + * `SIGNED` - подпись успешно наложена; + * `FAILED` - попытка наложения подписи завершилась с ошибкой + enum: + - SIGNED + - FAILED + errorCode: + type: string + description: Код ошибки при подписании + errorMessage: + type: string + description: Сообщение об ошибке при подписании + description: Электронные подписи по дайджесту документа + example: + signatureType: RSA + errorMessage: errorMessage + errorCode: errorCode + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + status: SIGNED + EscrowBuildProject: + type: object + properties: + buildingPermitNumber: + type: string + description: Номер РНС (разрешение на строительство) + example: 61-310-998601-2022 + regionCode: + type: string + description: Код региона + example: "054" + projectNumber: + type: string + description: Номер проекта строительства + example: "162" + settlement: + type: string + description: Наименование населенного пункта + example: Новосибирск + commercialName: + type: string + description: Коммерческое обозначение объекта + example: ЖК ЗАПАДНЫЕ АЛЛЕИ + city: + type: string + description: Город + example: Новосибирск + area: + type: string + description: Наименование района + example: ОКТЯБРЬСКИЙ + country: + type: string + description: Код страны + example: RU + buildingPermitDate: + type: string + description: Дата РНС + format: date + example: 2021-10-01 + phases: + type: array + description: Этапы строительства + items: + $ref: '#/components/schemas/EscrowBuildProjectPhase' + example: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01T00:00:00.000+00:00 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + EscrowBuildProjectPhase: + type: object + properties: + index: + type: integer + description: Порядковый номер этапа строительства в пределах проекта + example: 1 + name: + type: string + description: Краткое имя этапа строительства + example: поз. 4.1 - 9-этажный 4-х секц дом + street: + type: string + description: Улица объекта недвижимости + example: 11-4 на земельном участке с к.н. 61:44:0073012:390 + house: + type: string + description: Номер дома объекта недвижимости + example: "4.1" + building: + type: string + description: Номер строения\корпуса + example: "2" + termEscrowOrder: + type: string + description: Срок учета и блокирования депонированной суммы на счете эскроу + по ДДУ + format: date + example: 2022-03-22 + example: + street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + FilterStatusesV0: + type: string + description: | + Статусы заявок: + * `VERIFICATION` - Пользователь внес все данные по заявке и нажал "Отправить заявку" + * `CLIENT_CANCELLED` - Депонент изменил решение по открытию счета эскроу + * `VERIFICATION_ERROR` - Депонент не прошел проверку (Отклонена банком) + * `SIGNING` - Все проверки пройдены, эскроу-счет зарезервирован. Ожидается подписание заявления депонента в офисе Банка + * `WAITING_DDU` - Депонент подписал заявление в офисе Банка, счет эскроу переведен в бух. режим, ожидается регистрация ДДУ застройщиком + * `EXECUTED` - Заявление депонента подписано, получена отметка от застройщика о факте регистрации ДДУ + enum: + - VERIFICATION + - CLIENT_CANCELLED + - VERIFICATION_ERROR + - SIGNING + - WAITING_DDU + - EXECUTED + GetEscrowOrdersV0Response: + type: object + properties: + pagination: + $ref: '#/components/schemas/GetEscrowOrdersPagination' + items: + type: array + items: + $ref: '#/components/schemas/GetEscrowOrdersV0Items' + description: Ответ на запрос получения списка заявок застройщика + example: + pagination: + offset: 0 + limit: 10 + totalCount: 25 + items: + - escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + - escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + GetEscrowOrdersPagination: + type: object + properties: + limit: + type: integer + description: Количество объектов на одной странице + example: 10 + offset: + type: integer + description: "Количество объектов в списке, которые необходимо пропустит\ + ь" + example: 0 + totalCount: + type: integer + description: Общее количество записей + example: 25 + description: Информация о пагинации + example: + offset: 0 + limit: 10 + totalCount: 25 + GetEscrowOrdersV0Items: + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + example: EA10509220000013 + creationDate: + type: string + description: Дата создания заявки + format: date + example: 2021-12-10 + status: + $ref: '#/components/schemas/FilterStatusesV0' + fullNameDepositor: + type: string + description: ФИО депонента + example: Королёв Митрофан Гертрудович + buildingPermitNumber: + type: string + description: Номер РНС + example: 61-310-998601-2022 + escrowAccount: + $ref: '#/components/schemas/GetEscrowOrdersEscrowAccount' + description: Заявка застройщика + example: + escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + GetEscrowOrdersEscrowAccount: + type: object + properties: + amount: + type: number + description: Депонируемая сумма + format: bigDecimal + example: 6000000.12 + currency: + type: string + description: Валюта + example: RUR + accountNumber: + type: string + description: Номер счета эскроу + example: "40702810701300000761" + description: Счет эскроу + example: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + CreateEscrowOrderRequest: + required: + - depositor + - equalityAgreement + - escrowAccount + - estateObject + type: object + properties: + depositor: + $ref: '#/components/schemas/CreateEscrowOrderDepositor' + escrowAccount: + $ref: '#/components/schemas/CreateEscrowOrderEscrowAccount' + estateObject: + $ref: '#/components/schemas/CreateEscrowOrderEstateObject' + equalityAgreement: + $ref: '#/components/schemas/CreateEscrowOrderEqualityAgreement' + example: + escrowAccount: + amount: 112500.0 + currency: RUR + estateObject: + flat: "1" + buildProject: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + type: APARTMENTS + depositor: + lastName: Федькин + firstName: Ратибор + birthdate: 1990-08-30T00:00:00.000+00:00 + phoneNumber: "75453333435" + identityDocumentNumber: "197343" + dateIssuedId: 2020-01-01T00:00:00.000+00:00 + identityDocumentType: "001" + middleName: Васильевич + identityDocumentSeries: "5516" + equalityAgreement: + date: 2020-01-01T00:00:00.000+00:00 + number: "5555" + CreateEscrowOrderDepositor: + required: + - birthdate + - dateIssuedId + - firstName + - identityDocumentNumber + - identityDocumentSeries + - identityDocumentType + - lastName + - phoneNumber + type: object + properties: + lastName: + maxLength: 35 + type: string + description: Фамилия депонента + example: Федькин + firstName: + maxLength: 35 + type: string + description: Имя депонента + example: Ратибор + middleName: + maxLength: 35 + type: string + description: Отчество депонента + example: Васильевич + birthdate: + type: string + description: Дата рождения депонента + format: date + example: 1990-08-30 + identityDocumentType: + type: string + description: | + Тип ДУЛа: + * `001` - Паспорт гражданина РФ + * `002` - Загранпаспорт гражданина РФ + enum: + - "001" + - "002" + identityDocumentSeries: + type: string + description: Серия ДУЛ депонента + example: "5516" + identityDocumentNumber: + type: string + description: Номер ДУЛ депонента + example: "197343" + dateIssuedId: + type: string + description: Дата выдачи ДУЛ депонента + format: date + example: 2020-01-01 + phoneNumber: + pattern: "^(7\\d{10})$" + type: string + description: Мобильный телефон депонента + example: "75453333435" + description: Депонент + example: + lastName: Федькин + firstName: Ратибор + birthdate: 1990-08-30T00:00:00.000+00:00 + phoneNumber: "75453333435" + identityDocumentNumber: "197343" + dateIssuedId: 2020-01-01T00:00:00.000+00:00 + identityDocumentType: "001" + middleName: Васильевич + identityDocumentSeries: "5516" + CreateEscrowOrderEscrowAccount: + required: + - amount + - currency + type: object + properties: + amount: + maximum: 9999999999999.99 + minimum: 1.0 + type: number + description: Депонируемая сумма + format: bigDecimal + example: 112500.0 + currency: + type: string + description: | + Валюта: + * `RUR` - Рублевая валюта + enum: + - RUR + description: Счет эскроу + example: + amount: 112500.0 + currency: RUR + CreateEscrowOrderEstateObject: + required: + - buildProject + - flat + - type + type: object + properties: + type: + type: string + description: | + Типы объектов недвижимости: + * `APARTMENTS` - Апартаменты + * `COMMERCIAL_PREMISES` - Коммерческое помещение + * `FLAT` - Квартира + * `GARAGE` - Гараж + * `NON_RESIDENTIAL_PREMISES` - Нежилое помещение + * `PANTRY` - Кладовая + * `PARKING` - Машиноместо + * `ROOM` - Комната + * `RESIDENTIAL_PREMISES` - Жилой дом + enum: + - APARTMENTS + - COMMERCIAL_PREMISES + - FLAT + - GARAGE + - NON_RESIDENTIAL_PREMISES + - PANTRY + - PARKING + - ROOM + - RESIDENTIAL_PREMISES + flat: + maxLength: 35 + type: string + description: Номер квартиры объекта недвижимости + example: "1" + buildProject: + $ref: '#/components/schemas/CreateEscrowOrderBuildProject' + description: Объект строительства + example: + flat: "1" + buildProject: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + type: APARTMENTS + CreateEscrowOrderBuildProject: + required: + - buildingPermitNumber + - phases + type: object + properties: + buildingPermitNumber: + maxLength: 70 + type: string + description: Номер РНС (разрешение на строительство) + example: 61-310-998601-2022 + phases: + $ref: '#/components/schemas/CreateEscrowOrderBuildProjectPhase' + description: Информация об объекте строительства + example: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + CreateEscrowOrderBuildProjectPhase: + required: + - index + type: object + properties: + index: + type: integer + description: Порядковый номер этапа строительства в пределах проекта + example: 1 + description: Этап строительства + example: + index: 1 + CreateEscrowOrderEqualityAgreement: + required: + - date + - number + type: object + properties: + number: + maxLength: 50 + type: string + description: Номер ДДУ + example: "5555" + date: + type: string + description: Дата подписания ДДУ + format: date + example: 2020-01-01 + description: Договор Долевого Участия (ДДУ) + example: + date: 2020-01-01T00:00:00.000+00:00 + number: "5555" + CreateEscrowOrderResponse: + required: + - referenceID + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + example: EA10509220000013 + example: + referenceID: EA10509220000013 + CreateEscrowOrderErrorConflict: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: conflict + error_description: + type: string + description: Сообщение об ошибке + example: The data of the depositor is not uniquely defined + FilterStatusesV1: + type: string + description: | + Статусы заявок: + * `VERIFICATION` - Пользователь внес все данные по заявке и нажал "Отправить заявку" + * `CLIENT_CANCELLED` - Депонент изменил решение по открытию счета эскроу + * `VERIFICATION_ERROR` - Депонент не прошел проверку (Отклонена банком) + * `SIGNING` - Все проверки пройдены, эскроу-счет зарезервирован. Ожидается подписание заявления депонента в офисе Банка + * `WAITING_DDU` - Депонент подписал заявление в офисе Банка, счет эскроу переведен в бух. режим, ожидается регистрация ДДУ застройщиком + * `EXECUTED` - Заявление депонента подписано, получена отметка от застройщика о факте регистрации ДДУ + * `DRAFT` - Пользователь сохранил черновик заявки + enum: + - VERIFICATION + - CLIENT_CANCELLED + - VERIFICATION_ERROR + - SIGNING + - WAITING_DDU + - EXECUTED + - DRAFT + GetEscrowOrdersV1Response: + type: object + properties: + pagination: + $ref: '#/components/schemas/GetEscrowOrdersPagination' + items: + type: array + items: + $ref: '#/components/schemas/GetEscrowOrdersV1Items' + description: Ответ на запрос получения списка заявок застройщика + example: + pagination: + offset: 0 + limit: 10 + totalCount: 25 + items: + - escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + - escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + GetEscrowOrdersV1Items: + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + example: EA10509220000013 + creationDate: + type: string + description: Дата создания заявки + format: date + example: 2021-12-10 + status: + $ref: '#/components/schemas/FilterStatusesV1' + fullNameDepositor: + type: string + description: ФИО депонента + example: Королёв Митрофан Гертрудович + buildingPermitNumber: + type: string + description: Номер РНС + example: 61-310-998601-2022 + escrowAccount: + $ref: '#/components/schemas/GetEscrowOrdersEscrowAccount' + description: Заявка застройщика + example: + escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-10T00:00:00.000+00:00 + referenceID: EA10509220000013 + status: null + GetEscrowOrderV0Response: + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + example: EA10808220000061 + rejectReason: + type: string + description: Причина отказа банка + example: "К сожалению, во время обработки произошла тех. ошибка." + creationDate: + type: string + description: Дата создания заявки + format: date + example: 2021-12-31 + status: + $ref: '#/components/schemas/FilterStatusesV0' + escrowAccount: + $ref: '#/components/schemas/GetEscrowOrderEscrowAccount' + depositor: + $ref: '#/components/schemas/GetEscrowOrderDepositor' + equalityAgreement: + $ref: '#/components/schemas/GetEscrowOrderEqualityAgreement' + estateObject: + $ref: '#/components/schemas/GetEscrowOrderEstateObject' + example: + escrowAccount: + amount: 8.008281904619307E11 + currency: RUR + accountNumber: "40824810906580000000" + estateObject: + flat: "234" + buildProject: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01T00:00:00.000+00:00 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + type: APARTMENTS + rejectReason: "К сожалению, во время обработки произошла тех. ошибка." + depositor: + birthdate: 1998-11-03T00:00:00.000+00:00 + phoneNumber: "79055485717" + identityDocumentNumber: "615760" + dateIssuedId: 2022-04-25T00:00:00.000+00:00 + identityDocumentType: "001" + fullName: Королёв Митрофан Гертрудович + identityDocumentSeries: "8039" + creationDate: 2021-12-31T00:00:00.000+00:00 + referenceID: EA10808220000061 + equalityAgreement: + date: 2022-07-14T00:00:00.000+00:00 + number: "234" + isRegistered: false + status: null + GetEscrowOrderEscrowAccount: + type: object + properties: + accountNumber: + type: string + description: Номер счета эскроу + example: "40824810906580000000" + amount: + maximum: 9999999999999.99 + minimum: 1.0 + type: number + description: Депонируемая сумма + format: bigDecimal + currency: + type: string + description: | + Валюта: + * `RUR` - Рублевая валюта + enum: + - RUR + description: Счет эскроу + example: + amount: 8.008281904619307E11 + currency: RUR + accountNumber: "40824810906580000000" + GetEscrowOrderDepositor: + type: object + properties: + fullName: + type: string + description: ФИО Депонента + example: Королёв Митрофан Гертрудович + birthdate: + type: string + description: День рождения депонента + format: date + example: 1998-11-03 + identityDocumentSeries: + pattern: "^(\\d{2}|\\d{4})$" + type: string + description: Серия ДУЛ депонента + example: "8039" + identityDocumentNumber: + pattern: "^(\\d{6}|\\d{7})$" + type: string + description: Номер ДУЛ депонента + example: "615760" + identityDocumentType: + type: string + description: | + Тип ДУЛа: + * `001` - Паспорт гражданина РФ + * `002` - Загранпаспорт гражданина РФ + enum: + - "001" + - "002" + phoneNumber: + type: string + description: Номер телефона депонента + example: "79055485717" + dateIssuedId: + type: string + description: Дата выдачи ДУЛ депонента + format: date + example: 2022-04-25 + description: Депонент + example: + birthdate: 1998-11-03T00:00:00.000+00:00 + phoneNumber: "79055485717" + identityDocumentNumber: "615760" + dateIssuedId: 2022-04-25T00:00:00.000+00:00 + identityDocumentType: "001" + fullName: Королёв Митрофан Гертрудович + identityDocumentSeries: "8039" + GetEscrowOrderEqualityAgreement: + type: object + properties: + number: + type: string + description: Номер ДДУ + example: "234" + date: + type: string + description: Дата ДДУ + format: date + example: 2022-07-14 + isRegistered: + type: boolean + description: Регистрация ДДУ в Росреестре + example: false + description: Договор Долевого Участия (ДДУ) + example: + date: 2022-07-14T00:00:00.000+00:00 + number: "234" + isRegistered: false + GetEscrowOrderEstateObject: + type: object + properties: + type: + type: string + description: | + Типы объектов недвижимости: + * `APARTMENTS` - Апартаменты + * `COMMERCIAL_PREMISES` - Коммерческое помещение + * `FLAT` - Квартира + * `GARAGE` - Гараж + * `NON_RESIDENTIAL_PREMISES` - Нежилое помещение + * `PANTRY` - Кладовая + * `PARKING` - Машиноместо + * `ROOM` - Комната + * `RESIDENTIAL_PREMISES` - Жилой дом + enum: + - APARTMENTS + - COMMERCIAL_PREMISES + - FLAT + - GARAGE + - NON_RESIDENTIAL_PREMISES + - PANTRY + - PARKING + - ROOM + - RESIDENTIAL_PREMISES + flat: + type: string + description: Номер квартиры объекта недвижимости (квартиры/комнаты/гаража) + example: "234" + buildProject: + $ref: '#/components/schemas/EscrowBuildProject' + description: Объект строительства + example: + flat: "234" + buildProject: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01T00:00:00.000+00:00 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + type: APARTMENTS + GetEscrowOrderV1Response: + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + example: EA10808220000061 + rejectReason: + type: string + description: Причина отказа банка + example: "К сожалению, во время обработки произошла тех. ошибка." + creationDate: + type: string + description: Дата создания заявки + format: date + example: 2021-12-31 + status: + $ref: '#/components/schemas/FilterStatusesV1' + escrowAccount: + $ref: '#/components/schemas/GetEscrowOrderEscrowAccount' + depositor: + $ref: '#/components/schemas/GetEscrowOrderDepositor' + equalityAgreement: + $ref: '#/components/schemas/GetEscrowOrderEqualityAgreement' + estateObject: + $ref: '#/components/schemas/GetEscrowOrderEstateObject' + example: + escrowAccount: + amount: 8.008281904619307E11 + currency: RUR + accountNumber: "40824810906580000000" + estateObject: + flat: "234" + buildProject: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01T00:00:00.000+00:00 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22T00:00:00.000+00:00 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + type: APARTMENTS + rejectReason: "К сожалению, во время обработки произошла тех. ошибка." + depositor: + birthdate: 1998-11-03T00:00:00.000+00:00 + phoneNumber: "79055485717" + identityDocumentNumber: "615760" + dateIssuedId: 2022-04-25T00:00:00.000+00:00 + identityDocumentType: "001" + fullName: Королёв Митрофан Гертрудович + identityDocumentSeries: "8039" + creationDate: 2021-12-31T00:00:00.000+00:00 + referenceID: EA10808220000061 + equalityAgreement: + date: 2022-07-14T00:00:00.000+00:00 + number: "234" + isRegistered: false + status: null + CancelOrderV1Response: + required: + - referenceID + - status + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + status: + type: string + description: Статус заявки + enum: + - CLIENT_CANCELLED + description: Ответ на запрос отмены заявки на резервирование счета эскроу + example: + referenceID: referenceID + status: CLIENT_CANCELLED + ExecuteEscrowOrderRequest: + required: + - equalityAgreement + type: object + properties: + equalityAgreement: + $ref: '#/components/schemas/ExecuteEscrowOrderEqualityAgreement' + example: + equalityAgreement: + isRegistered: true + ExecuteEscrowOrderEqualityAgreement: + required: + - isRegistered + type: object + properties: + isRegistered: + type: boolean + description: Регистрация ДДУ в Росреестре + example: true + description: Договор Долевого Участия (ДДУ) + example: + isRegistered: true + CreateFullOrderV1Request: + title: CreateFullOrderRequest + required: + - depositor + - equalityAgreement + - escrowAccount + - estateObject + type: object + properties: + depositor: + $ref: '#/components/schemas/CreateFullOrderV1Depositor' + escrowAccount: + $ref: '#/components/schemas/CreateEscrowOrderEscrowAccount' + estateObject: + $ref: '#/components/schemas/CreateEscrowOrderEstateObject' + equalityAgreement: + $ref: '#/components/schemas/CreateEscrowOrderEqualityAgreement' + description: Запрос для создания заявки с расширенными параметрами + example: + escrowAccount: + amount: 112500.0 + currency: RUR + estateObject: + flat: "1" + buildProject: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + type: APARTMENTS + depositor: + lastName: Федькин + birthdate: 1990-08-30T00:00:00.000+00:00 + identityDocumentNumber: "615760" + dateIssuedId: 1995-08-30T00:00:00.000+00:00 + identityDocumentType: "001" + firstName: Ратибор + birthPlace: г. Москва + managerContactEmail: manager@gmail.com + phoneNumber: "79055485717" + middleName: Васильевич + managerContactPhoneNumber: "79055485717" + regAddress: ул. Центральная + identityDocumentSeries: "5516" + equalityAgreement: + date: 2020-01-01T00:00:00.000+00:00 + number: "5555" + CreateFullOrderV1Depositor: + title: CreateEscrowOrderDepositor + required: + - birthPlace + - birthdate + - dateIssuedId + - firstName + - identityDocumentNumber + - identityDocumentSeries + - identityDocumentType + - lastName + - phoneNumber + - regAddress + type: object + properties: + lastName: + maxLength: 35 + type: string + description: Фамилия депонента + example: Федькин + firstName: + maxLength: 35 + type: string + description: Имя депонента + example: Ратибор + middleName: + maxLength: 35 + type: string + description: Отчество депонента + example: Васильевич + birthdate: + type: string + description: День рождения депонента + format: date + example: 1990-08-30 + identityDocumentType: + type: string + description: | + Тип ДУЛа: + * `001` - Паспорт гражданина РФ + * `002` - Загранпаспорт гражданина РФ + enum: + - "001" + - "002" + identityDocumentSeries: + pattern: "^(\\d{2}|\\d{4})$" + type: string + description: Серия ДУЛ депонента + example: "5516" + identityDocumentNumber: + pattern: "^(\\d{6}|\\d{7})$" + type: string + description: Номер ДУЛ депонента + example: "615760" + dateIssuedId: + type: string + description: Дата выдачи ДУЛ депонента + format: date + example: 1995-08-30 + birthPlace: + type: string + description: Место рождения + example: г. Москва + regAddress: + type: string + description: Адрес регистрации + example: ул. Центральная + managerContactPhoneNumber: + type: string + description: Контактный номер телефона менеджера клиента для уточнения данных + о депоненте + example: "79055485717" + managerContactEmail: + type: string + description: Контактная адрес электронной почты менеджера клиента для уточнения + данных о депоненте + example: manager@gmail.com + phoneNumber: + type: string + description: Мобильный телефон депонента + example: "79055485717" + description: Депонент + example: + lastName: Федькин + birthdate: 1990-08-30T00:00:00.000+00:00 + identityDocumentNumber: "615760" + dateIssuedId: 1995-08-30T00:00:00.000+00:00 + identityDocumentType: "001" + firstName: Ратибор + birthPlace: г. Москва + managerContactEmail: manager@gmail.com + phoneNumber: "79055485717" + middleName: Васильевич + managerContactPhoneNumber: "79055485717" + regAddress: ул. Центральная + identityDocumentSeries: "5516" + CreateFullOrderV1Response: + title: CreateFullOrderResponse + required: + - referenceID + - status + type: object + properties: + referenceID: + type: string + description: Номер заявки на резервирование счета эскроу + status: + $ref: '#/components/schemas/FilterStatusesV1' + example: + referenceID: referenceID + status: null + EscrowReportsBuildProjectsV1Response: + title: EscrowReportsBuildProjectsV1Response + type: object + properties: + organizationName: + type: string + description: Наименование застройщика + example: Тестовый пользователь + organizationFullName: + type: string + description: Полное наименование застройщика + example: Тестовый пользователь Номер один + buildProjects: + type: array + description: Информация об объектах строительства + items: + $ref: '#/components/schemas/EscrowReportsBuildProjectsV1ResponseBuildProject' + example: + organizationName: Тестовый пользователь + buildProjects: + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + organizationFullName: Тестовый пользователь Номер один + EscrowReportsBuildProjectsV1ResponseBuildProject: + title: EscrowReportsBuildProjectsV1ResponseBuildProject + type: object + properties: + buildPermitNumber: + type: string + description: Номер РНС (разрешение на строительство) + example: №599-35-92-2024 + projectNumber: + type: string + description: Номер проекта строительства + example: 503-302 + commercialName: + type: string + description: Коммерческое обозначение объекта + example: Тестовый жилой комплекс + actualProjectCompletionDate: + type: string + description: Дата РНС + example: 2024-02-10T00:00:00.000Z + phases: + type: array + description: Этапы строительства + items: + $ref: '#/components/schemas/EscrowReportsBuildProjectsV1ResponseBuildProjectPhase' + example: + buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + EscrowReportsBuildProjectsV1ResponseBuildProjectPhase: + title: EscrowReportsBuildProjectsV1ResponseBuildProjectPhase + type: object + properties: + index: + type: integer + description: Порядковый номер этапа строительства в пределах проекта + example: 1 + name: + type: string + description: Краткое имя этапа строительства + example: Дом + termEscrowOrder: + type: string + description: Срок учета и блокирования депонированной суммы на счете эскроу + по ДДУ + example: 2024-02-10T00:00:00.000Z + example: + termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + EscrowReportsGenerateReportV1Request: + title: EscrowReportsGenerateReportV1Request + required: + - buildProjects + - showAccountTransactions + type: object + properties: + buildProjects: + type: array + description: Список объектов строительства застройщика + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1RequestBuildProject' + showAccountTransactions: + type: boolean + description: Признак отображения транзакций + example: true + example: + buildProjects: + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + showAccountTransactions: true + EscrowReportsGenerateReportV1RequestBuildProject: + title: EscrowReportsGenerateReportV1RequestBuildProject + required: + - buildPermitNumber + - phases + - projectNumber + type: object + properties: + buildPermitNumber: + type: string + description: Номер РНС (разрешение на строительство) + example: №599-35-92-2024 + projectNumber: + type: string + description: Номер проекта строительства + example: 503-302 + commercialName: + type: string + description: Коммерческое обозначение объекта + example: Тестовый жилой комплекс + actualProjectCompletionDate: + type: string + description: Дата РНС + example: 2024-02-10T00:00:00.000Z + phases: + type: array + description: Этапы строительства + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1RequestBuildProjectPhase' + example: + buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + - termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + commercialName: Тестовый жилой комплекс + EscrowReportsGenerateReportV1RequestBuildProjectPhase: + title: EscrowReportsGenerateReportV1RequestBuildProjectPhase + required: + - index + type: object + properties: + index: + type: integer + description: Порядковый номер этапа строительства в пределах проекта + example: 1 + name: + type: string + description: Краткое имя этапа строительства + example: Дом + termEscrowOrder: + type: string + description: Срок учета и блокирования депонированной суммы на счете эскроу + по ДДУ + example: 2024-02-10T00:00:00.000Z + example: + termEscrowOrder: 2024-02-10T00:00:00.000Z + name: Дом + index: 1 + EscrowReportsGenerateReportV1Response: + title: EscrowReportsGenerateReportV1Response + type: object + properties: + report: + type: array + description: Данные отчета + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1ResponseReport' + example: + report: + - pagination: + - offset: 2 + limit: 10 + totalCount: 90 + - offset: 2 + limit: 10 + totalCount: 90 + escrowAccountInfo: + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + commonInfo: + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + - pagination: + - offset: 2 + limit: 10 + totalCount: 90 + - offset: 2 + limit: 10 + totalCount: 90 + escrowAccountInfo: + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + commonInfo: + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + EscrowReportsGenerateReportV1ResponseReport: + title: EscrowReportsGenerateReportV1ResponseReport + type: object + properties: + pagination: + type: array + description: Пагинация для формирования отчета + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1ResponseReportPagination' + commonInfo: + type: array + description: Базовая информация отчета + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1ResponseReportCommonInfo' + escrowAccountInfo: + type: array + description: Массив данных с информацией о счетах + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfo' + example: + pagination: + - offset: 2 + limit: 10 + totalCount: 90 + - offset: 2 + limit: 10 + totalCount: 90 + escrowAccountInfo: + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + - escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + commonInfo: + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + - reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + EscrowReportsGenerateReportV1ResponseReportPagination: + title: EscrowReportsGenerateReportV1ResponseReportPagination + type: object + properties: + limit: + type: integer + description: Количество возвращаемых записей + example: 10 + offset: + type: integer + description: Количество записей для смещения + example: 2 + totalCount: + type: integer + description: Общее количество записей + example: 90 + example: + offset: 2 + limit: 10 + totalCount: 90 + EscrowReportsGenerateReportV1ResponseReportCommonInfo: + title: EscrowReportsGenerateReportV1ResponseReportCommonInfo + type: object + properties: + customerNameTo: + type: string + description: Наименование организации застройщика + example: Тестовая организация ИНН 0000000 + periodTo: + type: string + description: Конечная дата периода для формирования отчета + example: 2024-02-10T00:00:00.000Z + periodFrom: + type: string + description: Начальная дата периода для формирования отчета + example: 2022-02-10T00:00:00.000Z + reportGenerationDate: + type: string + description: Дата формирования отчета + example: 2024-02-10T00:00:00.000Z + example: + reportGenerationDate: 2024-02-10T00:00:00.000Z + periodTo: 2024-02-10T00:00:00.000Z + customerNameTo: Тестовая организация ИНН 0000000 + periodFrom: 2022-02-10T00:00:00.000Z + EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfo: + title: EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfo + type: object + properties: + buildPermitNumber: + type: string + description: Номер РНС + example: №599-35-92-2024 + commercialName: + type: string + description: Наименование проекта строительства + example: Тестовый жилой комплекс + buildProjectPhase: + type: integer + description: Порядковый номер этапа строительства в пределах проекта + example: 2 + phaseDescription: + type: string + description: Наименование этапа строительства + example: Паркинг + escrowAccountNumber: + type: string + description: Номер счета + example: "40824810906580012508" + escrowAccountCurrentStatus: + type: string + description: Текущий статус + example: Пополнен + escrowAccountOpenDate: + type: string + description: Дата открытия счета + example: 2024-02-10T00:00:00.000Z + apartmentCost: + type: string + description: Стоимость объекта по ДДУ в рублях + example: "12600000.55" + incomingBalance: + type: string + description: "Входящий остаток на начало периода, RUB" + example: "0.00" + outcomingBalance: + type: string + description: "Исходящий остаток на конец периода, RUB" + example: "12600000.55" + balanceChange: + type: string + description: "Изменение остатка за период отчета, RUB" + example: "12600000.55" + depositCompletionDate: + type: string + description: Дата завершения срока условного депонирования + example: 2024-02-10T00:00:00.000Z + deponentName: + type: string + description: ФИО депозитора + example: Сергеев Сергей Сергеевич + deponentINN: + type: string + description: ИНН депозитора + example: "184514811334" + shareAgreementNumber: + type: string + description: Данные договора об участии счета + example: 22-444/111П-1234 + shareAgreementDate: + type: string + description: Дата ДДУ + example: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: + type: string + description: Номер договора переуступки + example: ДУ 103-4 от 12.02.2023 + assignmentAgreementDate: + type: string + description: Дата договора переуступки + example: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: + type: string + description: Дата закрытия счета + example: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: + type: string + description: Предоставлен зарегистрированный ДДУ + example: "Y" + escrowAccountReservePlace: + type: string + description: Место резервирования счёта эскроу + example: Онлайн + escrowAccountOpenPlace: + type: string + description: Место открытия счёта эскроу + example: Онлайн + developerManger: + type: string + description: "ФИО менеджера застройщика, который завел заявку на резерви\ + рование счета" + example: Иванов Иван Иванович + objectType: + type: string + description: Вид помещения + example: Комната + transactions: + type: array + description: Массив проводок + items: + $ref: '#/components/schemas/EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfoTransactions' + example: + escrowAccountCurrentStatus: Пополнен + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + phaseDescription: Паркинг + objectType: Комната + buildProjectPhase: 2 + assignmentAgreementDate: 2024-02-10T00:00:00.000Z + commercialName: Тестовый жилой комплекс + escrowAccountReservePlace: Онлайн + buildPermitNumber: №599-35-92-2024 + depositCompletionDate: 2024-02-10T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + developerManger: Иванов Иван Иванович + incomingBalance: "0.00" + deponentName: Сергеев Сергей Сергеевич + transactions: + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + escrowAccountNumber: "40824810906580012508" + outcomingBalance: "12600000.55" + escrowAccountOpenPlace: Онлайн + apartmentCost: "12600000.55" + balanceChange: "12600000.55" + shareAgreementDate: 2024-02-10T00:00:00.000Z + escrowAccountCloseDate: 2024-02-10T00:00:00.000Z + escrowAccountOpenDate: 2024-02-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfoTransactions: + title: EscrowReportsGenerateReportV1ResponseReportEscrowAccountInfoTransactions + type: object + properties: + operationDate: + type: string + description: Дата ввода полупроводки + example: 2024-02-10T00:00:00.000Z + transactionAmount: + type: string + description: Определяет сумму транзакции со знаком в минимальных единицах + валюты счета + example: "150000.55" + primaryDocumentDate: + type: string + description: Дата платежного документа по операции + example: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: + type: string + description: Номер платежного документа» (первичного документа) по операции + example: "350" + bicBank: + type: string + description: БИК банка отправителя по операции + example: "044525593" + example: + operationDate: 2024-02-10T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2024-02-10T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + ScoringAny: + required: + - borrower + - dealId + - partner + type: object + properties: + dealId: + pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" + type: string + description: "Идентификатор черновика заявки (UUID, 128-битный)" + format: uuid + example: c5f72949-0e9a-41bf-a16d-a34b938f41ef + borrower: + $ref: '#/components/schemas/Borrower' + application: + $ref: '#/components/schemas/Application' + partner: + $ref: '#/components/schemas/Partner' + example: + application: + platformId: B2B + partner: + income: "12000234" + startDateOfInteraction: 2022-05-01T00:00:00.000+00:00 + twoPersonalIncomeTaxesInfo: + retentionSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + paidSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + employeesQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + fullCostSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + sellerInventory: + inventorySumAndQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + vat: + counterparts: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + totalTaxBaseList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + purchaseAndSaleOperations: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + numberOfInteractionDays: 149 + transportedGoodsInfo: + deliveries: + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + feeList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 3000000.76 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 3000000.76 + insurancePremiumsInfo: + mandatorySocialInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryMedicalInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSurchargeSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + supplementarySocialSupportSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + procuredGoodsInfo: + categories: + - Категория 1 + - Категория 2 + profitTax: + incomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + costs: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + totalProfits: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + delay: + loans: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + goods: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + orderInfo: + date: 2023-10-25T00:00:00.000+00:00 + number: 2023-123-234-3459 ОТ + amount: 328400 + productCode: Рассрочка для партнёра + returnUrl: + success: https://partner.example.ru/success + failure: https://partner.example.ru/failure + sellerQuality: + returnedQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + goodsConcentrationLevels: + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + sellerRatings: + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + reasonForRefundList: + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + calculationsInformation: + currentInterestsSum: 110687 + currentInterestsAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentFinesAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentTaxesSum: 5016161.68 + paymentDetails: + bankDetails: + recipientAccount: "30101810200000000593" + bankBIC: "044525593" + bankCorrespondentAccount: "30101810200000000593" + recipientName: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + bankName: "АО «Альфа-Банк», г. Москва" + recipientINN: "5504036333" + recipientKPP: "783801001" + vat: true + vatAmount: 1.239857567345E10 + sixPersonalIncomeTaxesInfo: + imposedKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + retentionPITDateAndSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + paidKBKFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + factIncomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + imposedInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + imposedFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + transactionsInfo: + minSumTransactionMSB: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBMaxSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBAvgSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + premiumAccount: + hasPremiumAccount: true + dealId: c5f72949-0e9a-41bf-a16d-a34b938f41ef + borrower: + individual: + legalInfo: + ogrn: "305465110922043" + inn: "770778659011" + kpp: "770201001" + contactPhone: +7(495)545-00-10 + legal: + legalInfo: + ogrn: "1027739642281" + inn: "7707786590" + kpp: "770201001" + contactPhone: +7(916)545-00-00 + Borrower: + type: object + properties: + individual: + $ref: '#/components/schemas/Individual' + legal: + $ref: '#/components/schemas/Legal' + description: Информация о заёмщике + example: + individual: + legalInfo: + ogrn: "305465110922043" + inn: "770778659011" + kpp: "770201001" + contactPhone: +7(495)545-00-10 + legal: + legalInfo: + ogrn: "1027739642281" + inn: "7707786590" + kpp: "770201001" + contactPhone: +7(916)545-00-00 + Individual: + type: object + properties: + legalInfo: + $ref: '#/components/schemas/IndividualInfo' + description: Информация о заёмщике-ИП + example: + legalInfo: + ogrn: "305465110922043" + inn: "770778659011" + kpp: "770201001" + contactPhone: +7(495)545-00-10 + IndividualInfo: + required: + - inn + type: object + properties: + inn: + pattern: "^\\d{12}$" + type: string + description: ИНН ИП + nullable: false + example: "770778659011" + kpp: + pattern: "^\\d{9}$" + type: string + description: КПП (код причины постановки на учёт) ИП + nullable: false + example: "770201001" + ogrn: + pattern: "^\\d{15}$" + type: string + description: ОГРН (основной государственный регистрационный номер) ИП + nullable: false + example: "305465110922043" + contactPhone: + pattern: "^\\+7\\(\\d{3}\\)\\d{3}-\\d{2}-\\d{2}$|^\\+7\\(\\d{4}\\)\\d{2}-\\\ + d{2}-\\d{2}$" + type: string + description: Контактный номер телефон ИП + example: +7(495)545-00-10 + description: Информация о заёмщике + example: + ogrn: "305465110922043" + inn: "770778659011" + kpp: "770201001" + contactPhone: +7(495)545-00-10 + Legal: + type: object + properties: + legalInfo: + $ref: '#/components/schemas/LegalInfo' + description: Информация о заёмщике-юр.лице + example: + legalInfo: + ogrn: "1027739642281" + inn: "7707786590" + kpp: "770201001" + contactPhone: +7(916)545-00-00 + LegalInfo: + required: + - inn + type: object + properties: + inn: + pattern: "^\\d{10}$" + type: string + description: ИНН Юр.лица + nullable: false + example: "7707786590" + kpp: + pattern: "^\\d{9}$" + type: string + description: КПП (код причины постановки на учёт) Юр.лица + nullable: false + example: "770201001" + ogrn: + pattern: "^\\d{13}$" + type: string + description: ОГРН (основной государственный регистрационный номер) Юр.лица + nullable: false + example: "1027739642281" + contactPhone: + pattern: "^\\+7\\(\\d{3}\\)\\d{3}-\\d{2}-\\d{2}$|^\\+7\\(\\d{4}\\)\\d{2}-\\\ + d{2}-\\d{2}$" + type: string + description: Контактный номер телефона юр.лица + example: +7(916)545-00-00 + description: Информация о заёмщике + example: + ogrn: "1027739642281" + inn: "7707786590" + kpp: "770201001" + contactPhone: +7(916)545-00-00 + Application: + type: object + properties: + platformId: + type: string + description: Тип взаимодействия с партнером + example: B2B + description: Вспомогательная информация для приложения банка + example: + platformId: B2B + Partner: + type: object + properties: + numberOfInteractionDays: + type: number + description: Количество дней с даты начала работы с партнёром + format: integer + example: 149 + startDateOfInteraction: + type: string + description: Дата начала работы с партнёром + format: date + example: 2022-05-01 + orderInfo: + $ref: '#/components/schemas/Order' + paymentDetails: + $ref: '#/components/schemas/Payment_1' + income: + type: string + description: Выручка клиента за последние 12 месяцев в рублях + example: "12000234" + transactionsInfo: + $ref: '#/components/schemas/TransactionsInfo' + sellerInventory: + $ref: '#/components/schemas/SellerInventory' + sellerQuality: + $ref: '#/components/schemas/SellerQuality' + premiumAccount: + $ref: '#/components/schemas/PremiumAccount' + delay: + $ref: '#/components/schemas/Delay' + procuredGoodsInfo: + $ref: '#/components/schemas/ProcuredGoodsInfo' + feeList: + type: array + description: Оплата услуг партнёра + items: + $ref: '#/components/schemas/Fee' + transportedGoodsInfo: + $ref: '#/components/schemas/TransportedGoodsInfo' + vat: + $ref: '#/components/schemas/Vat_2' + insurancePremiumsInfo: + $ref: '#/components/schemas/InsurancePremiumsInfo' + profitTax: + $ref: '#/components/schemas/ProfitTax' + twoPersonalIncomeTaxesInfo: + $ref: '#/components/schemas/TwoPersonalIncomeTaxesInfo' + sixPersonalIncomeTaxesInfo: + $ref: '#/components/schemas/SixPersonalIncomeTaxesInfo' + calculationsInformation: + $ref: '#/components/schemas/CalculationsInformation' + description: Информация о работе заёмщика с партнёром + example: + income: "12000234" + startDateOfInteraction: 2022-05-01T00:00:00.000+00:00 + twoPersonalIncomeTaxesInfo: + retentionSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + paidSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + employeesQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + fullCostSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + sellerInventory: + inventorySumAndQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + vat: + counterparts: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + totalTaxBaseList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + purchaseAndSaleOperations: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + numberOfInteractionDays: 149 + transportedGoodsInfo: + deliveries: + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + feeList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 3000000.76 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 3000000.76 + insurancePremiumsInfo: + mandatorySocialInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryMedicalInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSurchargeSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + supplementarySocialSupportSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + procuredGoodsInfo: + categories: + - Категория 1 + - Категория 2 + profitTax: + incomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + costs: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + totalProfits: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + delay: + loans: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + goods: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + orderInfo: + date: 2023-10-25T00:00:00.000+00:00 + number: 2023-123-234-3459 ОТ + amount: 328400 + productCode: Рассрочка для партнёра + returnUrl: + success: https://partner.example.ru/success + failure: https://partner.example.ru/failure + sellerQuality: + returnedQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + goodsConcentrationLevels: + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + sellerRatings: + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + reasonForRefundList: + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + calculationsInformation: + currentInterestsSum: 110687 + currentInterestsAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentFinesAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentTaxesSum: 5016161.68 + paymentDetails: + bankDetails: + recipientAccount: "30101810200000000593" + bankBIC: "044525593" + bankCorrespondentAccount: "30101810200000000593" + recipientName: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + bankName: "АО «Альфа-Банк», г. Москва" + recipientINN: "5504036333" + recipientKPP: "783801001" + vat: true + vatAmount: 1.239857567345E10 + sixPersonalIncomeTaxesInfo: + imposedKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + retentionPITDateAndSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + paidKBKFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + factIncomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + imposedInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + imposedFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + transactionsInfo: + minSumTransactionMSB: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBMaxSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBAvgSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + premiumAccount: + hasPremiumAccount: true + Order: + required: + - amount + - date + - returnUrl + type: object + properties: + productCode: + type: string + description: "Продукт Банка, который выбрал клиент" + example: Рассрочка для партнёра + number: + type: string + description: Номер договора партнёра с клиентом на осуществление заказа + example: 2023-123-234-3459 ОТ + date: + type: string + description: Дата заключения договора между клиентом и партнёром на осуществление + заказа + format: date + example: 2023-10-25 + amount: + minimum: 0 + type: number + description: Сумма заказа в рублях + format: integer + example: 328400 + returnUrl: + $ref: '#/components/schemas/ReturnURL' + description: Информация о заказе клиента у партнёра + example: + date: 2023-10-25T00:00:00.000+00:00 + number: 2023-123-234-3459 ОТ + amount: 328400 + productCode: Рассрочка для партнёра + returnUrl: + success: https://partner.example.ru/success + failure: https://partner.example.ru/failure + ReturnURL: + required: + - failure + - success + type: object + properties: + success: + type: string + description: Ссылка редиректа при успешной операции + example: https://partner.example.ru/success + failure: + type: string + description: Ссылка редиректа при неуспешной операции + example: https://partner.example.ru/failure + description: Информация о ссылках для редиректа пользователя после успешной + или неуспешной операции + example: + success: https://partner.example.ru/success + failure: https://partner.example.ru/failure + Payment_1: + required: + - vat + type: object + properties: + vat: + type: boolean + description: Признак включённого/невключённого НДС + example: true + vatAmount: + minimum: 0 + type: number + description: "Сумма включённого НДС в рублях. Передаётся, если `vat` рав\ + ен `true`" + format: float + example: 12398575673.45 + bankDetails: + $ref: '#/components/schemas/Bank_1' + description: Информация о реквизитах для проведения платежа партнёру + example: + bankDetails: + recipientAccount: "30101810200000000593" + bankBIC: "044525593" + bankCorrespondentAccount: "30101810200000000593" + recipientName: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + bankName: "АО «Альфа-Банк», г. Москва" + recipientINN: "5504036333" + recipientKPP: "783801001" + vat: true + vatAmount: 1.239857567345E10 + Bank_1: + required: + - bankBIC + - bankCorrespondentAccount + - bankName + - recipientAccount + - recipientINN + - recipientName + type: object + properties: + bankName: + type: string + description: Название Банка получателя платежа + nullable: false + example: "АО «Альфа-Банк», г. Москва" + bankBIC: + type: string + description: БИК Банка получателя + nullable: false + example: "044525593" + bankCorrespondentAccount: + type: string + description: Кор.счёт Банка получателя + nullable: false + example: "30101810200000000593" + recipientINN: + pattern: "(^\\d{10}$)|(^\\d{12}$)" + type: string + description: ИНН получателя + nullable: false + example: "5504036333" + recipientKPP: + pattern: "^\\d{9}$" + type: string + description: КПП получателя + nullable: false + example: "783801001" + recipientAccount: + type: string + description: Расчётный счёт получателя + nullable: false + example: "30101810200000000593" + recipientName: + type: string + description: Наименование получателя + nullable: false + example: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + description: Банковские реквизиты получателя платежа + example: + recipientAccount: "30101810200000000593" + bankBIC: "044525593" + bankCorrespondentAccount: "30101810200000000593" + recipientName: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + bankName: "АО «Альфа-Банк», г. Москва" + recipientINN: "5504036333" + recipientKPP: "783801001" + TransactionsInfo: + type: object + properties: + transactionsMSBSumList: + type: array + description: Сумма транзакций МСБ продавца с партнёром помесячно за последние + 2-3 года + items: + $ref: '#/components/schemas/TransactionsAny' + transactionsMSBQuantityList: + type: array + description: Кол-во транзакций МСБ продавца с партнёром помесячно за последние + 2-3 года + items: + $ref: '#/components/schemas/QuantityTransactions' + transactionsMSBAvgSumList: + type: array + description: Средние суммы транзакций МСБ продавца с партнёром помесячно + за последние 2-3 года + items: + $ref: '#/components/schemas/TransactionsAny' + minSumTransactionMSB: + type: array + description: Минимальная сумма одной транзакции МСБ продавца с партнёром + помесячно за последние 2-3 года + items: + $ref: '#/components/schemas/TransactionsAny' + transactionsMSBMaxSumList: + type: array + description: Максимальная сумма одной транзакции МСБ продавца с партнёром + помесячно за последние 2-3 года + items: + $ref: '#/components/schemas/TransactionsAny' + description: Транзакции продавца с партнёром + example: + minSumTransactionMSB: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBMaxSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBAvgSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + transactionsMSBQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + TransactionsAny: + type: object + properties: + sum: + type: number + description: "Суммы (sum - общая, avgSum - средняя, minSum - минимальная\ + , maxSum - максимальная) транзакций МСБ продавца с партнёром за месяц\ + \ в рублях" + format: float + example: 1000.15 + date: + type: string + description: Дата выполнения транзакции + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 1000.15 + QuantityTransactions: + type: object + properties: + quantity: + type: number + description: Кол-во транзакций МСБ продавца с партнёром за месяц + format: integer + example: 15 + date: + type: string + description: "Дата, соответствующая n кол-ву партнёром" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 15 + SellerInventory: + type: object + properties: + inventorySumAndQuantityList: + type: array + description: Объём запасов МСБ продавца на маркетплейсе в руб. помесячно + за последние 2-3 года + items: + $ref: '#/components/schemas/InventorySumAndQuantityList' + description: Запасы МСБ продавца + example: + inventorySumAndQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + InventorySumAndQuantityList: + type: object + properties: + sum: + type: number + description: Объём запасов МСБ продавца на маркетплейсе за месяц в рублях + format: float + example: 9000.25 + quantity: + type: number + description: Объём запасов МСБ продавца на маркетплейсе в шт. за месяц + format: integer + example: 2 + date: + type: string + description: "Дата, соответствующая указанному объёму запасов МСБ" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 2 + sum: 9000.25 + SellerQuality: + type: object + properties: + sellerRatings: + type: array + description: Рейтинг продавца на маркетплейсе помесячно за последние 2-3 + года + items: + $ref: '#/components/schemas/SellerRating' + returnedQuantityList: + type: array + description: "Количество возвратов, не выполненных заказов помесячно за\ + \ последние 2-3 года" + items: + $ref: '#/components/schemas/ReturnQuantity' + reasonForRefundList: + type: array + description: "Причины возвратов, не выполненных заказов помесячно за пос\ + ледние 2-3 года" + items: + $ref: '#/components/schemas/ReturnReasons' + goodsConcentrationLevels: + type: array + description: Уровень концентрации продаваемых товаров – доля каждого товара + в общем объёме продаж МСБ продавца (в руб.)/(в ед. товара) + items: + $ref: '#/components/schemas/ConcentrationLevelGoods' + description: Качество торговли МСБ продавца + example: + returnedQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + goodsConcentrationLevels: + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + sellerRatings: + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + - date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + reasonForRefundList: + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + - date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + SellerRating: + type: object + properties: + rating: + type: number + description: Рейтинг продавца на маркетплейсе за месяц в единицах оценивания + format: float + example: 3.98 + date: + type: string + description: "Дата, соответствующая указанному рейтингу" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + rating: 3.98 + ReturnQuantity: + type: object + properties: + quantity: + type: number + description: Количество возвратов / не выполненных заказов за месяц + format: integer + example: 12 + date: + type: string + description: "Дата, соответствующая указанному количеству возвратов / не\ + \ выполненных заказов" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 12 + ReturnReasons: + type: object + properties: + reason: + type: string + description: Причины возвратов/не выполненных заказов за месяц + example: Какая-то причина возврата или не выполнения заказа + date: + type: string + description: "Дата, соответствующая указанным причинам возвратов" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + reason: Какая-то причина возврата или не выполнения заказа + ConcentrationLevelGoods: + type: object + properties: + concentrationLevelOfSum: + type: number + description: Доля товара в общем объеме продаж (в рублях) МСБ продавца на + дату запроса в % + format: float + example: 23.5 + concentrationLevelOfQuantity: + type: number + description: Доля товара в общем объеме продаж (в количестве) МСБ продавца + на дату запроса в % + format: float + example: 53.2 + nameOfGood: + type: string + description: Наименование товара + example: Товар называется так + example: + concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + PremiumAccount: + type: object + properties: + hasPremiumAccount: + type: boolean + description: Наличие премиального аккаунта МСБ продавца на маркетплейсе + на дату запроса + example: true + description: Информация о премиальном аккаунте + example: + hasPremiumAccount: true + Delay: + type: object + properties: + loans: + type: array + description: "Рассрочка, кредиты, прочие финансовые продукты" + items: + $ref: '#/components/schemas/DelayAny' + goods: + type: array + description: "Купленные товары, логистические услуги" + items: + $ref: '#/components/schemas/DelayAny' + description: "Просочка по рассрочке, кредитам, прочим финансовым продуктам М\ + СБ с партнёром и/или по оплате за купленные товары, логистические услуги М\ + СБ партнёру" + example: + loans: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + goods: + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + DelayAny: + type: object + properties: + overDueDate: + type: string + description: "Дата выхода в просрочку по рассрочке, кредитам, прочим фин\ + ансовым продуктам МСБ с партнёром и/или по оплате за купленные товары\ + , логистические услуги МСБ партнёру за месяц за последние 2-3 года" + format: date + example: 2022-05-01 + duration: + type: number + description: "Кол-во дней просрочки по рассрочке, кредитам, прочим финан\ + совым продуктам МСБ с партнёром и/или по оплате за купленные товары, л\ + огистические услуги МСБ партнёру за месяц за последние 2-3 года" + format: integer + example: 12 + sum: + type: number + description: "Сумма просрочки по рассрочке, кредитам, прочим финансовым\ + \ продуктам МСБ с партнёром и/или по оплате за купленные товары, логис\ + тические услуги МСБ партнёру за месяц за последние 2-3 года" + format: float + example: 10000 + example: + duration: 12 + overDueDate: 2022-05-01T00:00:00.000+00:00 + sum: 10000 + ProcuredGoodsInfo: + type: object + properties: + categories: + type: array + description: "Категории товаров, которые МСБ закупает у партнёра" + example: + - Категория 1 + - Категория 2 + items: + type: string + description: Закупаемые товары + example: + categories: + - Категория 1 + - Категория 2 + Fee: + type: object + properties: + sum: + type: number + description: Объёмы оплаты за логистические услуги МСБ через партнёра за + месяц за последние 2-3 года в рублях + format: float + example: 3000000.76 + date: + type: string + description: "Дата, согласно указанному объёму" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 3000000.76 + TransportedGoodsInfo: + type: object + properties: + deliveries: + type: array + items: + $ref: '#/components/schemas/Deliveries' + description: Информация о перевозимых грузах + example: + deliveries: + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + Deliveries: + type: object + properties: + date: + type: string + description: "Дата, согласно указанному объёму перевозимых грузов" + format: date + transportedGoodsVolumeAndCategoryList: + type: array + items: + $ref: '#/components/schemas/TransportedGoods' + description: Информация о перевозимых грузах + example: + date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + TransportedGoods: + type: object + properties: + volume: + type: number + description: Объёмы перевозимых грузов через партнёра за месяц в тонно-километрах + format: float + example: 3456.65 + category: + type: string + description: Наименование категории перевозимых грузов за месяц + example: Категория груза + description: Информация по объёму и номенклатуре перевозимых грузов + example: + volume: 3456.65 + category: Категория груза + Vat_2: + type: object + properties: + totalTaxBaseList: + type: array + description: Общая налоговая база по НДС поквартально за последние 2-3 года + items: + $ref: '#/components/schemas/TaxPurchasesSalesAny' + counterparts: + type: array + description: Кол-во контрагентов МСБ клиента поквартально за последние 2-3 + года + items: + $ref: '#/components/schemas/Counterparts' + purchaseAndSaleOperations: + type: array + description: Кол-во операций по книгам покупок и продаж + items: + $ref: '#/components/schemas/OperationsPurchaseAndSale' + description: "Информация о НДС, поквартально" + example: + counterparts: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + totalTaxBaseList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + purchaseAndSaleOperations: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + TaxPurchasesSalesAny: + type: object + properties: + sum: + type: number + description: "Сумма (tax - общей налоговой базы по НДС, purchases - поку\ + пок, sales - продаж) за квартал в руб." + format: float + example: 554000.55 + date: + type: string + description: "Дата, соответствующая указанной сумме" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + Counterparts: + type: object + properties: + quantity: + type: number + description: Кол-во контрагентов МСБ клиента за квартал + format: integer + example: 346 + date: + type: string + description: "Дата, соответствующая указанному количеству контрагентов" + format: date + example: 2022-05-01 + purchases: + type: array + description: Сумма покупок по каждому контрагенту поквартально за последние + 2-3 года + items: + $ref: '#/components/schemas/TaxPurchasesSalesAny' + sales: + type: array + description: Сумма продаж по каждому контрагенту поквартально за последние + 2-3 года + items: + $ref: '#/components/schemas/TaxPurchasesSalesAny' + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 346 + purchases: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + sales: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 554000.55 + OperationsPurchaseAndSale: + type: object + properties: + quantity: + type: number + description: Кол-во операций по книгам покупок и продаж за квартал в шт. + format: integer + example: 554000 + date: + type: string + description: "Дата, соответствующая указанному количеству операций" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 554000 + InsurancePremiumsInfo: + type: object + properties: + mandatoryPensionInsuranceSumList: + type: array + description: "Сумма страховых взносов на обязательное пенсионное страхов\ + ание, подлежащая уплате поквартально за последние 2-3 года" + items: + $ref: '#/components/schemas/InsuranceAny' + mandatoryMedicalInsuranceSumList: + type: array + description: "Сумма страховых взносов на обязательное медицинское страхо\ + вание, подлежащая уплате поквартально за последние 2-3 года" + items: + $ref: '#/components/schemas/InsuranceAny' + mandatoryPensionInsuranceSurchargeSumList: + type: array + description: "Сумма страховых взносов на обязательное пенсионное страхов\ + ание по дополнительному тарифу, подлежащая уплате (может быть нескольк\ + о КБК) поквартально за последние 2-3 года" + items: + $ref: '#/components/schemas/InsuranceAny' + supplementarySocialSupportSumList: + type: array + description: "Сумма страховых взносов на дополнительное социальное обесп\ + ечение, подлежащая уплате за расчётный (отчётный) период (может быть н\ + есколько КБК) поквартально за последние 2-3 года" + items: + $ref: '#/components/schemas/InsuranceAny' + mandatorySocialInsuranceSumList: + type: array + description: Сумма страховых взносов на обязательное социальное страхование + на случай временной нетрудоспособности и в связи с материнством поквартально + за последние 2-3 года + items: + $ref: '#/components/schemas/InsuranceAny' + description: Расчёт по страховым взносам + example: + mandatorySocialInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryMedicalInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSurchargeSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + mandatoryPensionInsuranceSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + supplementarySocialSupportSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + InsuranceAny: + type: object + properties: + sum: + type: number + description: "Сумма страховых взносов (pension - обязательное пенсионное\ + , medical - обязательное медицинское, surcharge - доп.тариф обязательн\ + ого пенсионного, support - доп.социальное, social - обязательное социа\ + льное), подлежащая уплате за квартал в руб." + format: float + example: 7579815.57 + date: + type: string + description: "Дата, соответствующая указанной сумме" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 7579815.57 + ProfitTax: + type: object + properties: + incomes: + type: array + description: Доходы от реализации поквартально за последние 2-3 года + items: + $ref: '#/components/schemas/ProfitTaxAny' + costs: + type: array + description: Убытки (расходы) поквартально за последние 2-3 года + items: + $ref: '#/components/schemas/ProfitTaxAny' + totalProfits: + type: array + description: Итого прибыль (убыток) поквартально за последние 2-3 года + items: + $ref: '#/components/schemas/ProfitTaxAny' + description: Налог на прибыль + example: + incomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + costs: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + totalProfits: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + ProfitTaxAny: + type: object + properties: + sum: + type: number + description: "Сумма (income - дохода, costs - убытков/расходов, total -\ + \ итого) поквартально за квартал в руб." + format: float + example: 87770039.19 + date: + type: string + description: "Дата, соответствующая указанной сумме" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 8.777003919E7 + TwoPersonalIncomeTaxesInfo: + type: object + properties: + fullCostSumList: + type: array + description: "Сумма НДФЛ, исчисленная по годам за последние 2-3 года" + items: + $ref: '#/components/schemas/SumPITAny' + retentionSumList: + type: array + description: "Сумма НДФЛ, удержанная по годам за последние 2-3 года" + items: + $ref: '#/components/schemas/SumPITAny' + paidSumList: + type: array + description: "Сумма НДФЛ, перечисленная по годам за последние 2-3 года" + items: + $ref: '#/components/schemas/SumPITAny' + employeesQuantityList: + type: array + description: Численность сотрудников по годам за последние 2-3 года + items: + $ref: '#/components/schemas/QuantityEmployees' + description: 2-НДФЛ + example: + retentionSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + paidSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + employeesQuantityList: + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + - date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + fullCostSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + SumPITAny: + type: object + properties: + sum: + type: number + description: "Сумма НДФЛ (cost - исчисленная, retention - удержанная, paid\ + \ - перечисленная) за год в руб." + format: float + example: 58552.25 + date: + type: string + description: "Дата, соответствующая указанной сумме" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 58552.25 + QuantityEmployees: + type: object + properties: + quantity: + type: number + description: Численность сотрудников по годам за последние 2-3 года + format: integer + example: 134 + date: + type: string + description: "Дата, соответствующая указанному количеству" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + quantity: 134 + SixPersonalIncomeTaxesInfo: + type: object + properties: + factIncomes: + type: array + description: Дата фактически полученного дохода по годам за последние 2-3 + года + items: + $ref: '#/components/schemas/IncomeRetentionAny' + retentionPITDateAndSumList: + type: array + description: Дата и сумма удержанного НДФЛ по годам за последние 2-3 года + items: + $ref: '#/components/schemas/IncomeRetentionAny' + imposedKBKTaxes: + type: array + description: Начисленные налоги по КБК за год по годам за последние 2-3 + года + items: + $ref: '#/components/schemas/ImposedAny' + imposedInterests: + type: array + description: Начисленные пени по КБК за год по годам за последние 2-3 года + items: + $ref: '#/components/schemas/ImposedAny' + imposedFines: + type: array + description: Начисленные штрафы по КБК за год по годам за последние 2-3 + года + items: + $ref: '#/components/schemas/ImposedAny' + paidKBKTaxes: + type: array + description: Уплаченные налоги по КБК за год по годам за последние 2-3 года + items: + $ref: '#/components/schemas/PaidAny' + paidKBKInterests: + type: array + description: Уплаченные пени по КБК за год по годам за последние 2-3 года + items: + $ref: '#/components/schemas/PaidAny' + paidKBKFines: + type: array + description: Уплаченные штрафы по КБК за год по годам за последние 2-3 года + items: + $ref: '#/components/schemas/PaidAny' + description: 6-НДФЛ + example: + imposedKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + retentionPITDateAndSumList: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + paidKBKFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKTaxes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + paidKBKInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + factIncomes: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + imposedInterests: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + imposedFines: + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + - date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + IncomeRetentionAny: + type: object + properties: + factDate: + type: string + description: "Фактическая дата (factIncome - получения дохода, dateAndSumRetentionPIT\ + \ - удержания НДФЛ)" + format: date + example: 2022-05-28 + sum: + type: number + description: "Сумма (factIncome - фактически полученного дохода, dateAndSumRetentionPIT\ + \ - удержанного НДФЛ) за год в руб." + format: float + example: 247912.19 + date: + type: string + description: "Дата, соответствующая указанной фактической дате" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 247912.19 + factDate: 2022-05-28T00:00:00.000+00:00 + ImposedAny: + type: object + properties: + sum: + type: number + description: "Начисленные (taxes - налоги, interests - пени, fines - штр\ + афы) по КБК за год в руб." + format: float + example: 33346.47 + date: + type: string + description: "Дата, соответствующая указанной фактической дате" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 33346.47 + PaidAny: + type: object + properties: + sum: + type: number + description: "Уплаченные (taxes - налоги, interests - пени, fines - штра\ + фы) по КБК за год в руб." + format: float + example: 9110687.53 + date: + type: string + description: "Дата, соответствующая указанной фактической дате" + format: date + example: 2022-05-01 + example: + date: 2022-05-01T00:00:00.000+00:00 + sum: 9110687.53 + CalculationsInformation: + type: object + properties: + currentInterestsSum: + type: number + description: Текущие пени на дату запроса в руб. + format: float + example: 110687 + currentInterestsAndCategories: + type: array + description: Текущие пени (в разбивке по категориям) + items: + $ref: '#/components/schemas/InterestsFinesAny' + currentTaxesSum: + type: number + description: Текущие штрафы на дату запроса в руб. + format: float + example: 5016161.68 + currentFinesAndCategories: + type: array + description: Текущие штрафы (в разбивке по категориям) + items: + $ref: '#/components/schemas/InterestsFinesAny' + description: Справка о состоянии расчётов + example: + currentInterestsSum: 110687 + currentInterestsAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentFinesAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentTaxesSum: 5016161.68 + InterestsFinesAny: + type: object + properties: + sum: + type: number + description: "Текущие (interests - пени, fines - штрафы) в разбивке по к\ + атегориям на дату запроса в руб." + format: float + example: 20299.1 + category: + type: string + description: Категория текущих пени/штрафа + example: Категория пени/штрафа + example: + sum: 20299.1 + category: Категория пени/штрафа + ScoringAnyResponse: + required: + - dealId + type: object + properties: + dealId: + type: string + format: uuid + example: c5f72949-0e9a-41bf-a16d-a34b938f41ef + example: + dealId: c5f72949-0e9a-41bf-a16d-a34b938f41ef + StatusResponse: + required: + - dealId + - inn + - statusInfo + type: object + properties: + dealId: + pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" + type: string + description: Уникальный идентификатор сделки + format: uuid + example: aef72949-0e9a-41bf-a11d-abbbcccf1e22 + inn: + pattern: "^(\\d{10}|\\d{12})$" + type: string + description: Идентификационный номер налогоплательщика + example: "7751231950" + statusInfo: + $ref: '#/components/schemas/StatusInfoObject' + description: Данные статуса кредитной заявки + example: + statusInfo: + status: ОТКЛОНЕНА + statusExplanation: Пока не можем одобрить заявку + dealId: aef72949-0e9a-41bf-a11d-abbbcccf1e22 + inn: "7751231950" + StatusInfoObject: + required: + - status + - statusExplanation + type: object + properties: + status: + type: string + description: Статус сделки + example: ОТКЛОНЕНА + enum: + - РАССМОТРЕНИЕ ЗАЯВКИ + - ПОДТВЕРЖДЕНИЕ УСЛОВИЙ + - ПОДПИСАНИЕ + - В РАБОТЕ + - КРЕДИТ ОФОРМЛЕН + - ОТКЛОНЕНА + statusExplanation: + type: string + description: Пояснение к статусу + example: Пока не можем одобрить заявку + enum: + - Подпишите согласие на обработку персональных данных + - "Подтвердите условия и подпишите документы, чтобы получить кредит" + - "Подпишите документы удобным способом, чтобы получить кредит" + - "Проверяем документы — как будет готово решение, кредит появится в ваш\ + их кредитных продуктах" + - Сегодня кредит появится в ваших продуктах — им можно пользоваться сразу + - Пока не можем одобрить заявку + example: + status: ОТКЛОНЕНА + statusExplanation: Пока не можем одобрить заявку + BonusNumbersResponse: + required: + - bonusNumbers + type: object + properties: + bonusNumbers: + type: array + items: + $ref: '#/components/schemas/BonusNumber' + description: Бонусные номера карт + example: + bonusNumbers: + - number: number + typeLoyalty: typeLoyalty + - number: number + typeLoyalty: typeLoyalty + BonusNumber: + required: + - number + - typeLoyalty + type: object + properties: + number: + type: string + description: Список бонусных номеров карт клиента + typeLoyalty: + type: string + description: Тип лояльности + description: Бонусный номер карты и соответствующий тип лояльности + example: + number: number + typeLoyalty: typeLoyalty + UserComplianceGetResponse: + required: + - checkPassed + type: object + properties: + checkPassed: + type: boolean + description: | + Признак прохождения проверки. Принимает возможные значения: + * true - оказание услуги делегированной идентификации клиента возможно; + * false - оказание услуги делегированной идентификация клиента невозможно, данные клиента неактуальны + persData: + $ref: '#/components/schemas/PersData' + reasons: + type: array + description: "Причины, по которым проверка не пройдена (возвращаются тол\ + ько при checkPassed = false)." + items: + $ref: '#/components/schemas/_______________________' + description: Результаты проверки актуальности сведений клиента + example: + reasons: + - description: description + - description: description + persData: + identityDocumentNumber: identityDocumentNumber + givenName: givenName + citizenship: citizenship + inn: inn + birthDate: 2000-01-23 + actualAddressDetails: + zip: zip + area: area + country: country + localityShortName: localityShortName + housingNumber: housingNumber + town: town + city: city + street: street + houseNumber: houseNumber + streetShortName: streetShortName + region: region + apartmentNumber: apartmentNumber + birthPlace: birthPlace + identityDocumentIssueDate: 2000-01-23 + familyName: familyName + name: name + middleName: middleName + identityDocumentAuthorityName: identityDocumentAuthorityName + identityDocumentName: identityDocumentName + snils: snils + identityDocumentAuthorityCode: identityDocumentAuthorityCode + identityDocumentSeries: identityDocumentSeries + checkPassed: true + PersData: + type: object + properties: + givenName: + type: string + description: Имя клиента + familyName: + type: string + description: Фамилия клиента + middleName: + type: string + description: Отчество клиента + name: + type: string + description: Полное имя клиента + birthDate: + type: string + description: Дата рождения клиента (формат YYYY-MM-DD) + format: date + birthPlace: + type: string + description: Место рождения клиента + citizenship: + type: string + description: Гражданство клиента + inn: + type: string + description: ИНН клиента + snils: + type: string + description: СНИЛС клиента + identityDocumentName: + type: string + description: "Тип документа, удостоверяющего личность" + identityDocumentSeries: + type: string + description: Серия документа + identityDocumentNumber: + type: string + description: Номер документа + identityDocumentAuthorityCode: + type: string + description: "Код подразделения, выдавшего документ" + identityDocumentAuthorityName: + type: string + description: "Наименование органа, выдавшего документ" + identityDocumentIssueDate: + type: string + description: Дата выдачи документа (формат YYYY-MM-DD) + format: date + actualAddressDetails: + $ref: '#/components/schemas/ActualAddressDetails' + description: Персональные данные клиента (возвращаются только при checkPassed + = true). + example: + identityDocumentNumber: identityDocumentNumber + givenName: givenName + citizenship: citizenship + inn: inn + birthDate: 2000-01-23 + actualAddressDetails: + zip: zip + area: area + country: country + localityShortName: localityShortName + housingNumber: housingNumber + town: town + city: city + street: street + houseNumber: houseNumber + streetShortName: streetShortName + region: region + apartmentNumber: apartmentNumber + birthPlace: birthPlace + identityDocumentIssueDate: 2000-01-23 + familyName: familyName + name: name + middleName: middleName + identityDocumentAuthorityName: identityDocumentAuthorityName + identityDocumentName: identityDocumentName + snils: snils + identityDocumentAuthorityCode: identityDocumentAuthorityCode + identityDocumentSeries: identityDocumentSeries + ActualAddressDetails: + type: object + properties: + country: + type: string + description: Страна проживания + city: + type: string + description: Город проживания + zip: + type: string + description: Почтовый индекс + street: + type: string + description: Улица + region: + type: string + description: Код региона (субъекта РФ) + area: + type: string + description: Район или административный округ + localityShortName: + type: string + description: Краткое название населённого пункта + town: + type: string + description: "Населённый пункт (город, посёлок, деревня)" + streetShortName: + type: string + description: "Краткое название улицы (например, «ул.», «пр-т»)" + houseNumber: + type: string + description: Номер дома + housingNumber: + type: string + description: Номер корпуса или строения + apartmentNumber: + type: string + description: Номер квартиры + description: Адрес проживания клиента + example: + zip: zip + area: area + country: country + localityShortName: localityShortName + housingNumber: housingNumber + town: town + city: city + street: street + houseNumber: houseNumber + streetShortName: streetShortName + region: region + apartmentNumber: apartmentNumber + ComplianceRequest: + required: + - callbackUri + type: object + properties: + callbackUri: + type: string + description: | + URI, на который будет отправлен результат асинхронной проверки + format: uri + example: https://partner.example.com/api/compliance/result + example: + callbackUri: https://partner.example.com/api/compliance/result + OperationResponse: + type: object + properties: + operationId: + type: string + description: Уникальный идентификатор операции на запрос проверки идентификации + пользователя + example: 22413cd0-11d7-4a1a-826d-a82470c18a83 + example: + operationId: 22413cd0-11d7-4a1a-826d-a82470c18a83 + ErrorBadRequest_1: + required: + - error + type: object + properties: + error: + type: string + description: | + Код ошибки. Принимает возможные значения: + - `invalid_request` - отсутствуют обязательные параметры или тело запроса; + - `invalid_callbackUri` - передан некорректный callbackUri + example: invalid_callbackUri + error_description: + type: string + description: Описание ошибки + example: The required field callbackUri is missing or has an invalid format + description: Неверные или отсутствующие параметры или тело запроса + OperationResponse_1: + type: object + properties: + operationId: + type: string + description: Уникальный идентификатор операции на запрос упрощенной проверки + идентификации пользователя + example: 22413cd0-11d7-4a1a-826d-a82470c18a83 + example: + operationId: 22413cd0-11d7-4a1a-826d-a82470c18a83 + ResponeWebhooks: + type: object + properties: + limit: + type: integer + description: Количество объектов на одной странице + offset: + type: integer + description: "Количество объектов в списке, которые необходимо пропустит\ + ь" + totalCount: + type: integer + description: Общее количество записей + items: + type: array + description: Массив вебхуков + items: + $ref: '#/components/schemas/ResponeWebhook' + description: Ответ на получение списка вебхуков + example: + offset: 6 + limit: 0 + totalCount: 1 + items: + - data: + accounts: + - accounts + - accounts + callbackUri: callbackUri + statusDescriptions: + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + id: id + version: 5 + enabled: true + object: object + - data: + accounts: + - accounts + - accounts + callbackUri: callbackUri + statusDescriptions: + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + id: id + version: 5 + enabled: true + object: object + ArrayWebhooks: + type: array + description: Массив вебхуков + items: + $ref: '#/components/schemas/ResponeWebhook' + ResponeWebhook: + type: object + properties: + id: + type: string + description: Идентифкатор записи + object: + type: string + description: Объект + enabled: + type: boolean + description: Статус вебхука (выключен/включен) + callbackUri: + type: string + description: "URI партнера, на который будет отправляться вебхук" + version: + type: integer + description: Версия выписки + data: + $ref: '#/components/schemas/Data_1' + statusDescriptions: + type: array + description: Описание статусов вебхука + items: + $ref: '#/components/schemas/StatusDescription' + description: Ответ по вебхуку + example: + data: + accounts: + - accounts + - accounts + callbackUri: callbackUri + statusDescriptions: + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + - cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + id: id + version: 5 + enabled: true + object: object + Data_1: + type: object + properties: + accounts: + type: array + description: Объект + items: + type: string + description: Список счетов + example: + accounts: + - accounts + - accounts + StatusDescriptions: + type: array + description: Описание статусов вебхука + items: + $ref: '#/components/schemas/StatusDescription' + StatusDescription: + type: object + properties: + cause: + type: string + description: Причина выключения статуса + example: Revocation of agreement + description: + type: string + description: Описание причины + example: The webhook is disabled due to the agreement being revoked in Alfa + ID + description: Ответ на получение списка вебхуков + example: + cause: Revocation of agreement + description: The webhook is disabled due to the agreement being revoked in + Alfa ID + RequestPostWebhook: + type: object + properties: + object: + type: string + description: Объект + callbackUri: + type: string + description: "URI партнера, на который будет отправляться вебхук" + version: + type: integer + description: Версия выписки + data: + $ref: '#/components/schemas/Data_1' + description: Запрос на создание вебхука + example: + data: + accounts: + - accounts + - accounts + callbackUri: callbackUri + version: 0 + object: object + RequestPutWebhook: + type: object + properties: + object: + type: string + description: Объект + callbackUri: + type: string + description: "URI партнера, на который будет отправляться вебхук. Редакт\ + ировать можно только path, host должен оставаться неизменным" + enabled: + type: boolean + description: Статус вебхука (выключен/включен) + version: + type: integer + description: Версия выписки + data: + $ref: '#/components/schemas/Data_1' + description: Запрос на редактирование вебхука + example: + data: + accounts: + - accounts + - accounts + callbackUri: callbackUri + version: 0 + enabled: true + object: object + PostWebhooksEvent: + type: object + properties: + object: + type: string + description: Объект + example: ul_transaction_default + description: Запрос на создание транзакций + example: + object: ul_transaction_default + ReceiptAndPayoutList: + required: + - company + - digestSignatures + - externalId + - requisite + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + $ref: '#/components/schemas/ReceiptAndPayoutList_company' + requisite: + maxItems: 10000 + minItems: 1 + type: array + description: Реквизиты выплаты + items: + $ref: '#/components/schemas/ReceiptAndPayoutList_requisite_inner' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + description: Выплаты самозанятым с регистрацией чека в ФНС и проведением платежа + example: + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + accountNumber: "40702810606050000022" + requisite: + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + UUID: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + Vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + PayoutRequisite: + required: + - payoutTotalAmount + - payoutType + type: object + properties: + payoutType: + $ref: '#/components/schemas/PayoutType' + byAccount: + $ref: '#/components/schemas/PayoutRequisite_byAccount' + byPan: + $ref: '#/components/schemas/PayoutRequisite_byPan' + byPhone: + $ref: '#/components/schemas/PayoutRequisite_byPhone' + payoutTotalAmount: + type: string + description: Сумма выплаты + example: "10.00" + description: Платежные реквизиты получателя + example: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + PayoutType: + type: string + description: | + Тип выплаты: + * `ACCOUNT` - Выплата по реквизитам счета получателя + * `CARD` - Выплата на банковскую карту получателя + * `PHONE` - Выплата через СБП по номеру телефона + example: ACCOUNT + enum: + - ACCOUNT + - CARD + - PHONE + AccountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + Phone: + pattern: "^79\\d{9}$" + type: string + description: Телефон + example: "79130000011" + ReceiptRequisite: + required: + - incomeType + - operateDate + - receiptTotalAmount + - requestDate + - services + type: object + properties: + customerVatin: + maxLength: 12 + minLength: 10 + pattern: "^([0-9]{10}|[0-9]{12})$" + type: string + description: ИНН покупателя + example: "5566778899" + customerName: + maxLength: 128 + minLength: 1 + type: string + description: Наименование компании покупателя + example: ООО Петуния + incomeType: + $ref: '#/components/schemas/IncomeType' + operateDate: + type: string + description: "Дата расчета с самозанятым, которая будет указана в чеке" + format: date-time + example: 2023-01-18T13:36:42.703Z + requestDate: + type: string + description: Дата запроса на формирование чека + format: date-time + example: 2023-01-18T13:36:42.703Z + services: + maxItems: 6 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/ReceiptRequisite_services_inner' + receiptTotalAmount: + type: string + description: Сумма чека + example: "10.00" + description: Реквизиты чека + example: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + IncomeType: + type: string + description: | + Тип дохода: + * `FROM_INDIVIDUAL` - Доход от физического лица + * `FROM_LEGAL_ENTITY` - Доход от юридического лица или ИП + * `FROM_FOREIGN_AGENCY` - Доход от иностранной организации + example: FROM_FOREIGN_AGENCY + enum: + - FROM_INDIVIDUAL + - FROM_LEGAL_ENTITY + - FROM_FOREIGN_AGENCY + default: FROM_LEGAL_ENTITY + DigestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + ListResponse: + required: + - externalId + - requestId + type: object + properties: + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + description: Ответ на запрос загрузки данных в систему + example: + requestId: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + ErrorBadRequest_2: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_request + error_description: + type: string + description: Описание ошибки + example: Authorization header is not present in request headers + ErrorUnauthorized_1: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_token + error_description: + type: string + description: Описание ошибки + example: "The access token provided is expired, revoked, malformed, or invalid\ + \ for other reasons" + ErrorForbidden: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: insufficient_scope + error_description: + type: string + description: Описание ошибки + example: The request requires higher privileges than provided by the access + token + ErrorTooManyRequests: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: too_many_requests + error_description: + type: string + description: Описание ошибки + example: Too many requests + ErrorInternal_1: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: internal_error + error_description: + type: string + description: Описание ошибки + example: Internal server error + ErrorServiceUnavailable: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: service_unavailable + error_description: + type: string + description: Описание ошибки + example: Service Unavailable + ReceiptList: + required: + - digestSignatures + - externalId + - requisite + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + requisite: + maxItems: 10000 + minItems: 1 + type: array + description: Реквизиты чека + items: + $ref: '#/components/schemas/ReceiptList_requisite_inner' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + description: Декларация дохода в ФНС с получением чека (без проведения платежа) + example: + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + requisite: + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + CheckSelfemployedStatusAndPayoutList: + required: + - company + - digestSignatures + - externalId + - requisite + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + $ref: '#/components/schemas/CheckSelfemployedStatusAndPayoutList_company' + requisite: + maxItems: 10000 + minItems: 1 + type: array + description: Реквизиты выплаты + items: + $ref: '#/components/schemas/CheckSelfemployedStatusAndPayoutList_requisite_inner' + receiptRequisite: + $ref: '#/components/schemas/CheckSelfemployedStatusAndPayoutList_receiptRequisite' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + description: Выплаты самозанятым с предварительной проверкой статуса самозанятого + в ФНС + example: + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptRequisite: + receiptId: 200wr5cn4s + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + accountNumber: "40817810306050000000" + requisite: + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + PayoutList: + required: + - company + - digestSignatures + - externalId + - requisite + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + $ref: '#/components/schemas/ReceiptAndPayoutList_company' + requisite: + maxItems: 10000 + minItems: 1 + type: array + description: Реквизиты выплаты + items: + $ref: '#/components/schemas/PayoutList_requisite_inner' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + description: "Выплаты ФЛ, незарегистрированным в системе, без проверки их ст\ + атуса и декларации доходов" + example: + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + company: + accountNumber: "40702810606050000022" + requisite: + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + - selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + PersonalInformation: + required: + - name + - surname + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + surname: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Фамилия + example: Иванов + name: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Имя + example: Иван + patronymic: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Отчество + example: Иванoвич + description: Персональные данные самозанятого + example: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + PayoutListState: + required: + - createdDate + - externalId + - listStatus + - pagination + - requestId + - statementList + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + createdDate: + type: string + description: Дата и время создания запроса в системе + format: date-time + listStatus: + $ref: '#/components/schemas/PayoutListStatus' + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + error: + $ref: '#/components/schemas/Error' + statementList: + minItems: 1 + type: array + description: Список чеков и выплат в системе + items: + $ref: '#/components/schemas/StatementList_inner' + description: "Статус обработки выплат, загруженных в систему" + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + createdDate: 2000-01-23T04:56:07.000+00:00 + requestId: 8658d934-9527-413b-b23c-d87bb1e9824a + statementList: + - receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + errorRecord: + - field: field + message: error_description + - field: field + message: error_description + payoutStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: IN_PROGRESS + - receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + errorRecord: + - field: field + message: error_description + - field: field + message: error_description + payoutStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: IN_PROGRESS + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + listStatus: IN_PROGRESS + accountNumber: "40817810306050000000" + error: + error_description: error_description + error: error_code + Pagination_2: + type: object + properties: + limit: + maximum: 1000 + minimum: 1 + type: number + description: Количество записей на одной странице + example: 1000 + default: 100 + offset: + minimum: 0 + type: number + description: "Количество записей в списке, которые были пропущены" + example: 0 + default: 0 + totalCount: + minimum: 0 + type: number + description: Общее количество записей + example: 10000 + default: 0 + description: Данные пагинации + example: + offset: 0 + limit: 1000 + totalCount: 10000 + PayoutListStatus: + type: string + description: | + Статус исполнения загруженного списка выплат: + * `NEW` - Принят для последующей обработки + * `TOTAL_AMOUNT_CALCULATED` - Общая сумма подсчитана + * `FAILED_SIGNATURE` - Подпись не прошла проверку + * `OUT_OF_DATE` - Реестр отправлен после окончания операционного дня + * `SUCCESS` - Реестр обработан успешно + * `IN_PROGRESS` - В обработке + * `BALANCE_CHECKED` - Баланса достаточно для выплат + * `SIGNATURE_CHECKED` - Подпись проверена + * `FAILED_COMPLIANCE` - Комплаенс проверка не была пройдена + * `CLIENT_ACCOUNT_CHECKED` - Счет Клиента проверен в админ-модуле + * `FAILED_ACCOUNT_CHECK` - Счет Клиента не прошел проверку в админ-модуле + * `CLIENT_ACCOUNT_EQ_CHECKED` - Счет Клиента прошел проверку в Банке + * `FAILED_ACCOUNT_EQ_CHECK` - Счет Клиента не прошел проверку в Банке + * `TECHNICAL_ERROR` - Непредвиденная ошибка + * `FAILED_BALANCE` - Недостаточно средств на счету для выполнения выплат + * `ERROR` - Ошибка при обработке + * `PAYOUT_TIME_CHECKED` - Проверка времени загрузки реестра выполнена + example: IN_PROGRESS + enum: + - NEW + - TOTAL_AMOUNT_CALCULATED + - FAILED_SIGNATURE + - OUT_OF_DATE + - SUCCESS + - IN_PROGRESS + - BALANCE_CHECKED + - SIGNATURE_CHECKED + - FAILED_COMPLIANCE + - CLIENT_ACCOUNT_CHECKED + - FAILED_ACCOUNT_CHECK + - CLIENT_ACCOUNT_EQ_CHECKED + - FAILED_ACCOUNT_EQ_CHECK + - TECHNICAL_ERROR + - FAILED_BALANCE + - ERROR + - PAYOUT_TIME_CHECKED + Error: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: error_code + error_description: + type: string + description: Описание ошибки + example: error_description + description: Ошибки обработки загруженного списка + example: + error_description: error_description + error: error_code + StatementList: + minItems: 1 + type: array + description: Список чеков и выплат в системе + items: + $ref: '#/components/schemas/StatementList_inner' + ReceiptLink: + required: + - link + type: object + properties: + receiptId: + maxLength: 128 + minLength: 1 + type: string + description: Идентификатор чека в ФНС + example: 200wr5cn4s + link: + maxLength: 512 + minLength: 1 + type: string + description: Ссылка на чек с сайта ФНС + example: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + description: Референс чека + example: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + ReceiptStatus: + type: string + description: | + Статус чека в системе: + * NEW - Принят для последующей обработки + * READY - Успешно зарегистрирован + * FAILED - Ошибка в процессе регистрации чека + * CANCEL_REQUESTED - Запрос на аннулирование чека отправлен в ФНС + * IN_PROGRESS - В процессе обработки + * CANCEL_INCOME_REQUESTED_AUTOMATICALLY - Отправлен запрос в ФНС на аннулирование чека + * CANCELED_AUTOMATICALLY - Аннулирован автоматически системой + * FAILED_CANCEL - Ошибка аннулирования чека в ФНС + * CHECK_REFUND - Проконтролируйте возврат суммы сторнированного дохода на счет + * PARTNER_INFO - Чек был передан клиентом + example: IN_PROGRESS + enum: + - NEW + - READY + - FAILED + - CANCEL_REQUESTED + - IN_PROGRESS + - CANCEL_INCOME_REQUESTED_AUTOMATICALLY + - CANCELED_AUTOMATICALLY + - FAILED_CANCEL + - CHECK_REFUND + - PARTNER_INFO + PayoutStatus: + type: object + properties: + status: + type: string + description: | + Статус выплаты в системе: + * `NEW` - Принят для последующей обработки + * `READY` - Выплата успешно исполнена + * `FAILED` - Ошибка при исполнении выплаты + * `IN_PROGRESS` - В обработке + * `WAITING` - Ожидает поступления средств + * `BIND_CHECKED` - Проверка привязки самозанятого к компании успешна + * `SELFEMPLOYED_CHECKED` - Проверка самозанятого успешна + * `BALANCE_CHECKED` - Баланса достаточно + * `SELFEMPLOYED_TAXPAYER_CHECK` - Статус самозанятого проверяется в ФНС + * `PAYMENT_IN_PROGRESS` - Выплата в обработке + * `INCOME_REGISTRATION_REQUESTED` - Отправлен запрос в ФНС на регистрацию чека + * `TECHNICAL_ERROR` - Техническая ошибка + * `FAILED_SELFEMPLOYED_CHECK` - Самозанятый не имеет статус READY + * `FAILED_SELFEMPLOYED_TAXPAYER_CHECK` - Самозанятый не прошел проверку статуса в ФНС + * `FAILED_BIND_CHECK` - Самозанятый не привязан к компании + * `FAILED_EQ_ACCOUNT_PAY` - Внутренняя ошибка выплаты в Банке + * `REGISTRATION_RESTRICTIONS_IN_PROGRESS` - Статус самозанятого в процессе проверки в фнс + * `FULL_NAME_CHECKED` - ФИО проверено + * `FAILED_FULL_NAME_CHECK` - Проверка ФИО неуспешна + * `PAYMENT_DEFERRED` - Проведение выплаты отложено + * `AWAIT_EXTERNAL` - Внешний платеж ожидает исполнения + enum: + - NEW + - READY + - FAILED + - IN_PROGRESS + - WAITING + - BIND_CHECKED + - SELFEMPLOYED_CHECKED + - BALANCE_CHECKED + - SELFEMPLOYED_TAXPAYER_CHECK + - PAYMENT_IN_PROGRESS + - INCOME_REGISTRATION_REQUESTED + - TECHNICAL_ERROR + - FAILED_SELFEMPLOYED_CHECK + - FAILED_SELFEMPLOYED_TAXPAYER_CHECK + - FAILED_BIND_CHECK + - FAILED_EQ_ACCOUNT_PAY + - REGISTRATION_RESTRICTIONS_IN_PROGRESS + - FULL_NAME_CHECKED + - FAILED_FULL_NAME_CHECK + - PAYMENT_DEFERRED + - AWAIT_EXTERNAL + updatedDate: + type: string + description: Дата и время обновления статуса чека в системе + format: date-time + example: READY + ErrorRecord: + minItems: 0 + type: array + description: Ошибки обработки записей списка + items: + $ref: '#/components/schemas/ErrorRecord_inner' + ErrorNotFound_1: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + example: unknown_endpoint + error_description: + type: string + description: Описание ошибки + example: Endpoint is not found or not active + CancelReceiptList: + required: + - cancelReceipt + - digestSignatures + - externalId + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + cancelReceipt: + maxItems: 10000 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/CancelReceiptList_cancelReceipt_inner' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_inner' + description: Список аннулируемых чеков + example: + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + cancelReceipt: + - vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + - vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + - vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + - vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + - vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + CancelReasonCode: + type: string + description: | + Код причины аннулирования чека: + * `REGISTRATION_MISTAKE` - Чек сформирован ошибочно + * `REFUND` - Возврат средств + example: REFUND + enum: + - REGISTRATION_MISTAKE + - REFUND + PayoutResponse: + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + payoutsList: + minItems: 0 + type: array + items: + $ref: '#/components/schemas/PayoutResponse_payoutsList_inner' + description: "Информация о выплатах, загруженных в систему" + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + payoutsList: + - receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + payerAccountNumber: "40817810306050000000" + vatin: "112233445566" + createdDate: 2000-01-23T04:56:07.000+00:00 + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + requestId: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + payoutStatus: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: IN_PROGRESS + - receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + payerAccountNumber: "40817810306050000000" + vatin: "112233445566" + createdDate: 2000-01-23T04:56:07.000+00:00 + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + requestId: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + payoutStatus: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: IN_PROGRESS + SelfemployedList: + required: + - digestSignatures + - externalId + - selfemployed + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + selfemployed: + maxItems: 10000 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/Selfemployed' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_1_inner' + description: "Список самозанятых, добавляемых в систему" + example: + selfemployed: + - birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + - birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + - birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + - birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + - birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + externalId: externalId + UUID_1: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + Selfemployed: + required: + - address + - birthDate + - birthPlace + - citizenship + - passport + - personalInformation + - phone + type: object + properties: + personalInformation: + $ref: '#/components/schemas/PersonalInformation_1' + phone: + pattern: "^79\\d{9}$" + type: string + description: Телефон + example: "79130000011" + birthDate: + type: string + description: Дата рождения + format: date + example: 2000-03-02 + birthPlace: + maxLength: 128 + minLength: 1 + type: string + description: Место рождения + example: Г. Иркутск + citizenship: + $ref: '#/components/schemas/Citizenship' + passport: + $ref: '#/components/schemas/Selfemployed_passport' + address: + maxLength: 128 + minLength: 1 + type: string + description: Адрес проживания + example: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + idCard: + $ref: '#/components/schemas/IdCard' + description: Данные самозанятого + example: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + PersonalInformation_1: + required: + - name + - surname + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + surname: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Фамилия + example: Иванов + name: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Имя + example: Иван + patronymic: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Отчество + example: Иванoвич + description: Персональные данные самозанятого + example: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + Citizenship: + type: string + description: | + Гражданство: + * `RU` - РФ + * `BY` - Беларусь + * `AM` - Армения + * `KZ` - Казахстан + * `KG` - Киргизия + example: RU + enum: + - RU + - BY + - AM + - KZ + - KG + Passport: + required: + - authority + - codeOfIssue + - dateOfIssue + - number + - series + type: object + properties: + series: + pattern: "^\\d{4}$" + type: string + description: Номер паспорта РФ + example: "6953" + number: + pattern: "^\\d{6}$" + type: string + description: Номер паспорта РФ + example: "987435" + dateOfIssue: + type: string + description: Дата выдачи паспорта + format: date + example: 2022-03-02 + codeOfIssue: + pattern: "^\\d{3}-\\d{3}$" + type: string + description: "Код подразделения, выдавшего паспорт" + example: 123-321 + authority: + maxLength: 128 + minLength: 1 + type: string + description: "Орган, выдавший документ" + example: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + description: Паспорт гражданина РФ. Передается если citizenship равен RU + ForeignPassport: + required: + - authority + - dateOfExpiry + - dateOfIssue + - number + type: object + properties: + number: + pattern: "^[a-zA-Z0-9\\s]{1,16}$" + type: string + description: Номер паспорта иностранного гражданина + example: КВ133661 + dateOfIssue: + type: string + description: Дата выдачи паспорта + format: date + example: 2022-03-02 + dateOfExpiry: + type: string + description: Дата окончания действия паспорта + format: date + example: 2032-03-02 + authority: + maxLength: 128 + minLength: 1 + type: string + description: "Орган, выдавший документ" + example: УВД БОБРУЙСКОГО ГОРИСПОЛКОМА МОГИЛЕВСКОЙ ОБЛАСТИ + description: "Паспорт иностранного гражданина. Передается если citizenship р\ + авен BY, AM, KZ, KG" + IdCard: + required: + - dateOfEffective + - dateOfExpiry + - number + - type + type: object + properties: + type: + type: string + description: | + Тип документа, подтверждающего право проживания на территории РФ: + * `residencePermit` - Вид на жительство + * `residenceCertificate` - Документ удостоверяющий проживание + * `migrationCard` - Миграционная карта + enum: + - migrationCard + - residenceCertificate + - residencePermit + number: + maxLength: 20 + minLength: 1 + type: string + description: "Номер документа, подтверждающего право проживания" + example: "1234567" + dateOfEffective: + type: string + description: "Дата начала действия документа, подтверждающего право прож\ + ивания" + format: date + example: 2022-03-02 + dateOfExpiry: + type: string + description: "Дата окончания действия документа, подтверждающего право п\ + роживания" + format: date + example: 2024-03-02 + description: "Документ, подтверждающего право проживания на территории РФ. П\ + ередается если citizenship равен AM, KZ, KG" + example: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + DigestSignatures_1: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_1_inner' + ListResponse_1: + required: + - externalId + - requestId + type: object + properties: + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Ответ на запрос загрузки данных в систему + example: + requestId: requestId + externalId: externalId + SelfemployedListState: + required: + - createdDate + - externalId + - listStatus + - pagination + - requestId + - selfemployedAccount + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + listStatus: + $ref: '#/components/schemas/SelfEmployedListStatus' + createdDate: + type: string + description: Дата и время создания запроса в системе + format: date-time + selfemployedAccount: + minItems: 1 + type: array + description: Список самозанятых + items: + $ref: '#/components/schemas/SelfemployedAccount_inner' + error: + $ref: '#/components/schemas/Error' + description: Статус добавления самозанятых в систему + example: + selfemployedAccount: + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + createdDate: 2000-01-23T04:56:07.000+00:00 + requestId: requestId + externalId: externalId + listStatus: IN_PROGRESS + error: + error_description: error_description + error: error_code + SelfEmployedListStatus: + type: string + description: | + Статус обработки загруженного списка самозанятых: + * 'NEW' - Принят для последующей обработки + * 'SUCCESS' - Успешно обработан + * 'ERROR' - Ошибка в процессе обработки + * 'IN_PROGRESS' - В процессе обработки + * 'TECHNICAL_ERROR' - Непредвиденная техническая ошибка + * 'SIGNATURE_CHECKED' - Реестр прошел проверку подписи (промежуточный статус) + example: IN_PROGRESS + enum: + - NEW + - SUCCESS + - ERROR + - IN_PROGRESS + - TECHNICAL_ERROR + - SIGNATURE_CHECKED + SelfemployedAccount: + minItems: 1 + type: array + description: Список самозанятых + items: + $ref: '#/components/schemas/SelfemployedAccount_inner' + SelfEmployedStatus: + type: string + description: | + Статус самозанятого в системе: + * NEW - Принят для последующей обработки + * IN_PROGRESS - В процессе обработки + * READY - Успешно добавлен + * FAILED - Ошибка в процессе исполнения + * FAILED_SIGNATURE - Подпись не валидна + * FAILED_BIND - Самозанятым отклонен запрос на передачу прав Альфа-Банку + * FAILED_REGISTRATION - Постановка на учет отклонена ФНС + * FAILED_CHECK_TAXPAYER_STATUS - Получен непредвиденный ответ при проверке статуса в ФНС + * FAILED_VERIFY - Ошибка в процессе проверки данных самозанятого + * FAILED_AGREEMENT - Соглашение с Альфа-Банком не подписано самозанятым + * TECHNICAL_ERROR - Техническая ошибка + * BIND_REQUESTED - В процессе передачи прав - самозанятый должен подтвердить передачу прав Альфа-Банку в приложении ФНС Мой Налог + * REGISTRATION_REQUESTED - В ФНС отправлен запрос на регистрацию + * AGREEMENT_SIGNED - Соглашение подписано + * PASSPORT_CHECKED - Паспорт проверен + * CLIENT_DATA_CHECKED - Персональные данные проверены + * TAXPAYER_STATUS_REQUESTED - В ФНС отправлен запрос на проверку статуса самозанятого + * TAXPAYER_UNREGISTERED - Самозанятый снят с учета в ФНС + * TAXPAYER_UNBOUND - Самозанятым не предоставлены права Альфа-Банку в ФНС + * TAXPAYER_REGISTERED - Самозанятый поставлен на учет в ФНС + * SIGNATURE_CHECKED - Подпись проверена + * TAXPAYER_ALREADY_BOUND - Самозанятым предоставлены права Альфа-Банку в ФНС + * TAXPAYER_ALREADY_REGISTERED - Самозанятый уже был поставлен на учет в ФНС + enum: + - NEW + - IN_PROGRESS + - READY + - FAILED + - FAILED_SIGNATURE + - FAILED_BIND + - FAILED_REGISTRATION + - FAILED_CHECK_TAXPAYER_STATUS + - FAILED_VERIFY + - FAILED_AGREEMENT + - TECHNICAL_ERROR + - BIND_REQUESTED + - REGISTRATION_REQUESTED + - AGREEMENT_SIGNED + - PASSPORT_CHECKED + - CLIENT_DATA_CHECKED + - TAXPAYER_STATUS_REQUESTED + - TAXPAYER_UNREGISTERED + - TAXPAYER_UNBOUND + - TAXPAYER_REGISTERED + - SIGNATURE_CHECKED + - TAXPAYER_ALREADY_BOUND + - TAXPAYER_ALREADY_REGISTERED + ErrorRecord_1: + minItems: 0 + type: array + description: Ошибки обработки записей списка + items: + $ref: '#/components/schemas/ErrorRecord_1_inner' + RequestTaxpayerStatusList: + required: + - externalId + - selfemployedVatinList + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + selfemployedVatinList: + maxItems: 1 + minItems: 1 + type: array + description: "Список ИНН самозанятых, ограниченный одной записью" + items: + $ref: '#/components/schemas/Vatin' + description: Список самозанятых для запроса статуса в ФНС + example: + selfemployedVatinList: + - "112233445566" + externalId: externalId + SelfemployedVatin: + maxItems: 1 + minItems: 1 + type: array + description: "Список ИНН самозанятых, ограниченный одной записью" + items: + $ref: '#/components/schemas/Vatin' + TaxpayerListStatus: + required: + - externalId + - pagination + - requestId + - taxpayerStatusList + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + taxpayerStatusList: + minItems: 1 + type: array + items: + $ref: '#/components/schemas/TaxpayerListStatus_taxpayerStatusList_inner' + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + requestId: requestId + externalId: externalId + taxpayerStatusList: + - vatin: "112233445566" + status: TAXPAYER_BOUND + - vatin: "112233445566" + status: TAXPAYER_BOUND + AccrualList: + required: + - externalId + - selfemployedVatinList + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + selfemployedVatinList: + maxItems: 100 + minItems: 1 + type: array + description: Список ИНН самозанятых + items: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + description: Список самозанятых для запроса данных о неоплаченных налоговых + начислениях и задолжностях в ФНС + example: + selfemployedVatinList: + - "112233445566" + - "112233445566" + - "112233445566" + - "112233445566" + - "112233445566" + externalId: externalId + SelfemployedVatinList: + maxItems: 100 + minItems: 1 + type: array + description: Список ИНН самозанятых + items: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + AccrualAndDebtListStatus: + required: + - accrualList + - externalId + - pagination + - requestId + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + accrualList: + minItems: 1 + type: array + items: + $ref: '#/components/schemas/AccrualAndDebtListStatus_accrualList_inner' + error: + $ref: '#/components/schemas/Error' + description: Информация о неоплаченных налоговых начисления и задолженностях + самозанятого + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + requestId: requestId + externalId: externalId + error: + error_description: error_description + error: error_code + accrualList: + - vatin: "112233445566" + ftsError: ftsError + taxChargeList: + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + krsbList: + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: NEW + - vatin: "112233445566" + ftsError: ftsError + taxChargeList: + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + krsbList: + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: NEW + PaymentDocumentListStatus: + title: PaymentDocumentListStaus + required: + - externalId + - pagination + - paymentDocumentListState + - requestId + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + paymentDocumentListState: + required: + - status + - vatin + type: array + properties: + vatin: + $ref: '#/components/schemas/Vatin' + status: + type: string + description: | + Статус получения данных из ФНС по самозанятому: + * NEW - Принят для последующей обработки + * SUCCESS - Успешно обработан + * ERROR - Ошибка в процессе обработки + * IN_PROGRESS - В процессе обработки + example: NEW + enum: + - NEW + - SUCCESS + - ERROR + - IN_PROGRESS + ftsError: + type: string + description: Ошибка ФНС + example: Not found + paymentDocumentList: + minItems: 0 + type: array + description: Список платежных документов + items: + required: + - accrualType + - adress + - amount + - code101 + - code106 + - code107 + - code110 + - createdAt + - documentIndex + - dueDate + - internalId + - kbk + - name + - oktmo + - recipientAccount + - recipientBank + - recipientBankAccount + - recipientBic + - recipientKpp + - recipientName + - recipientVatin + - taxpayerVatin + type: object + properties: + accrualType: + type: string + description: | + Тип начисления: + * `TAX`– налоговое начисление + * `DEBT` – задолженность + * `PENALTY` – пеня + example: TAX + enum: + - NEW + - SUCCESS + - IN_PROGRESS + - ERROR + documentIndex: + type: string + description: Индекс документа (УИН) + name: + type: string + description: ФИО налогоплательщика + adress: + type: string + description: Адрес места жительства налогоплательщика + taxpayerVatin: + type: string + description: ИНН налогоплательщика + amount: + type: string + description: Сумма к оплате + example: "10.00" + recipientBank: + type: string + description: Банк получателя + recipientBic: + type: string + description: БИК банка получателя + recipientBankAccount: + type: string + description: Счет банка получателя + recipientName: + type: string + description: Получатель + recipientAccount: + type: string + description: Счет получателя + recipientVatin: + type: string + description: ИНН получателя + recipientKpp: + type: string + description: КПП получателя + kbk: + type: string + description: КБК налогового начисления или КРСБ + oktmo: + type: string + description: ОКТМО налогового начисления или КРСБ + code101: + type: string + description: Код для поля 101 + example: "13" + code106: + type: string + description: | + Код для поля 106: + * `ТП` – оплата по налогам за текущий период + * `ЗД` – добровольное погашение задолженности по истекшим налоговым периодам + code107: + type: string + description: Код для поля 107 + example: 10.03.2023 + code110: + type: string + description: Код для поля 110 + example: "0" + dueDate: + type: string + description: Срок оплаты + format: date + example: 2022-03-02 + createdAt: + type: string + description: Дата/Время создания документа + format: date-time + internalId: + type: number + description: Внутренний идентификатор источника документа в ПП + НПД + error: + $ref: '#/components/schemas/Error' + description: "Данные платежных документов на оплату налоговых начислений, за\ + долженности и пеней самозанятого" + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + requestId: requestId + externalId: externalId + paymentDocumentListState: "" + SelfemployedResponse: + required: + - pagination + - selfemployedAccount + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_2' + selfemployedAccount: + minItems: 1 + type: array + description: Список самозанятых + items: + $ref: '#/components/schemas/SelfemployedAccount_inner' + description: "Информация о самозанятых, загруженных в систему" + example: + selfemployedAccount: + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + SelfemployedInfo: + required: + - createdDate + - selfemployed + - status + - updatedDate + type: object + properties: + selfemployed: + $ref: '#/components/schemas/Selfemployed' + status: + $ref: '#/components/schemas/SelfEmployedStatus' + createdDate: + type: string + description: Дата и время обновления статуса самозанятого в системе + format: date-time + updatedDate: + type: string + description: Дата и время обновления статуса самозанятого в системе + format: date-time + errorRecord: + minItems: 0 + type: array + description: Ошибки обработки записей списка + items: + $ref: '#/components/schemas/ErrorRecord_1_inner' + description: Детальная информация о самозанятом + example: + selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + RequestSelfemployedVatin: + required: + - requestUniqueRights + type: object + properties: + requestUniqueRights: + type: boolean + description: "Флаг проверки на уникальные права. `true` - запрашивается\ + \ расширенный список прав с `TAX_PAYMENT`. `false` - запрашивается ста\ + ндартный набор прав, без `TAX_PAYMENT`." + example: true + default: true + TaxpayerAccountStatusRequest: + required: + - externalId + - vatin + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + description: Запрос на получение информации о состоянии Лицевого счета НП НПД + example: + vatin: "112233445566" + externalId: externalId + TaxpayerAccountStatusResponse: + type: object + properties: + bonusAmount: + type: number + description: Сумма бонусного счета + example: 28.08 + unpaidAmmount: + type: number + description: Общая сумма неоплаченных платежей + example: 2916.5 + debtAmount: + type: number + description: Сумма задолжности (включена в общая сумму неоплаченных платежей) + example: 2916.5 + description: Информация о состоянии Лицевого счета НП НПД + example: + unpaidAmmount: 2916.5 + bonusAmount: 28.08 + debtAmount: 2916.5 + IncomeForPeriodRequest: + required: + - externalId + - taxPeriodId + - vatin + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + taxPeriodId: + type: string + description: ID налогового периода (YYYYMM) + example: "202306" + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + description: Запрос на получение информации по доходу НП НПД за период + example: + vatin: "112233445566" + taxPeriodId: "202306" + externalId: externalId + IncomeForPeriodResponse: + type: object + properties: + status: + type: string + description: Статус запроса + example: SUCCESS + totalAmount: + type: number + description: Сумма зарегистрированного дохода за период + example: 28.08 + canceledTotalAmount: + type: number + description: Сумма сторнированного дохода за период + example: 2916.5 + tax: + type: number + description: Рассчитанный налог за период + example: 2916.5 + description: Информация по доходу НП НПД за период + example: + totalAmount: 28.08 + canceledTotalAmount: 2916.5 + tax: 2916.5 + status: SUCCESS + IncomeV2Request: + required: + - externalId + - from + - to + - vatin + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + from: + type: string + description: "Дата, начиная с которой отображать зарегистрированные дохо\ + ды" + format: date-time + example: 2023-06-30T00:00:00+03:00 + to: + type: string + description: "Дата, до которой отображать зарегистрированные доходы" + format: date-time + example: 2023-06-30T23:59:59+03:00 + pagination: + $ref: '#/components/schemas/Pagination_2' + description: Запрос на получение информации по зарегистрированным доходам с + разбивкой по чекам + example: + vatin: "112233445566" + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + externalId: externalId + from: 2023-06-30T00:00:00+03:00 + to: 2023-06-30T23:59:59+03:00 + GetIncomeV2Response: + type: object + properties: + receipts: + type: array + description: Список полученных чеков + items: + $ref: '#/components/schemas/ReceiptV2' + description: Информации по зарегистрированным доходам с разбивкой по чекам + example: + receipts: + - totalAmount: 25.04 + customerVatin: customerVatin + partnerCode: partnerCode + incomeType: null + cancelationTime: 2023-06-30T16:17:57.874Z + taxPeriodId: "202306" + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + requestDate: 2023-06-30T16:17:57.874Z + services: + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + receiptId: 200wr5cn4s + operateDate: 2023-06-30T16:17:57.874Z + taxToPay: 1.38 + - totalAmount: 25.04 + customerVatin: customerVatin + partnerCode: partnerCode + incomeType: null + cancelationTime: 2023-06-30T16:17:57.874Z + taxPeriodId: "202306" + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + requestDate: 2023-06-30T16:17:57.874Z + services: + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + receiptId: 200wr5cn4s + operateDate: 2023-06-30T16:17:57.874Z + taxToPay: 1.38 + ReceiptV2: + type: object + properties: + receiptId: + maxLength: 128 + minLength: 1 + type: string + description: Идентификатор чека в ФНС + example: 200wr5cn4s + totalAmount: + type: number + description: Сумма чека + example: 25.04 + link: + maxLength: 512 + minLength: 1 + type: string + description: Ссылка на чек с сайта ФНС + example: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + incomeType: + $ref: '#/components/schemas/IncomeType_1' + requestDate: + type: string + description: Дата запроса на формирование чека + format: date-time + example: 2023-06-30T16:17:57.874Z + operateDate: + type: string + description: Дата расчета с самозаняты + format: date-time + example: 2023-06-30T16:17:57.874Z + taxPeriodId: + type: string + description: "Налоговый период, в котором при расчете налога будет/был у\ + чтен чек (формат, yyyyMM)" + example: "202306" + taxToPay: + type: number + description: Налог к уплате с данного чека (начисленный налог - использованный + бонус) + example: 1.38 + partnerCode: + type: string + description: ID банка/платформы-партнера + customerVatin: + type: string + description: ИНН поставщика данных(площадки третьего звена) + cancelationTime: + type: string + description: Дата сторнирования + format: date-time + example: 2023-06-30T16:17:57.874Z + services: + type: array + description: Список услуг + items: + $ref: '#/components/schemas/ReceiptV2_services_inner' + description: Информация о выписанном чеке + example: + totalAmount: 25.04 + customerVatin: customerVatin + partnerCode: partnerCode + incomeType: null + cancelationTime: 2023-06-30T16:17:57.874Z + taxPeriodId: "202306" + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + requestDate: 2023-06-30T16:17:57.874Z + services: + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + receiptId: 200wr5cn4s + operateDate: 2023-06-30T16:17:57.874Z + taxToPay: 1.38 + IncomeType_1: + type: string + description: | + Тип дохода: + * `FROM_INDIVIDUAL` - Доход от физического лица + * `FROM_LEGAL_ENTITY` - Доход от юридического лица или ИП + * `FROM_FOREIGN_AGENCY` - Доход от иностранной организации + enum: + - FROM_INDIVIDUAL + - FROM_LEGAL_ENTITY + - FROM_FOREIGN_AGENCY + default: FROM_LEGAL_ENTITY + AgreementPage: + type: object + properties: + phone: + pattern: "^79\\d{9}$" + type: string + description: Телефон + example: "79130000011" + activities: + minItems: 1 + type: array + items: + maxLength: 5 + minLength: 1 + type: string + description: Идентификатор вида деятельности + example: "17" + regions: + minItems: 1 + type: array + items: + maxLength: 8 + minLength: 8 + type: string + description: ОКТМО региона ведения деятельности + example: "40000000" + returnUrl: + maxLength: 256 + minLength: 1 + type: string + description: URL-адрес на который перенаправляется ФЛ после оформления соглашений + description: Параметры генерации страницы онбординга для оформления самозанятым + соглашений с Альфа-Банком + example: + regions: + - "40000000" + - "40000000" + phone: "79130000011" + activities: + - "17" + - "17" + returnUrl: returnUrl + AgreementPageUrl: + required: + - agreementPageId + - agreementPageLink + type: object + properties: + agreementPageId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + agreementPageLink: + type: string + description: Ссылка на страницу оформления соглашений + example: https://alfabank.ru/agreement/97ae89a6-2813-4d4d-a2a6-4a10adba9e1f + description: Результат генерации страницы онбординга по заданным параметрам + example: + agreementPageLink: https://alfabank.ru/agreement/97ae89a6-2813-4d4d-a2a6-4a10adba9e1f + agreementPageId: agreementPageId + Activities: + minItems: 1 + type: array + description: Список видов деятельности + items: + $ref: '#/components/schemas/Activities_inner' + Regions: + minItems: 1 + type: array + description: Список регионов ведения деятельности + items: + $ref: '#/components/schemas/Regions_inner' + SbpBanks: + type: array + items: + $ref: '#/components/schemas/SbpBanks_inner' + PoaNumber: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Номер МЧД + example: e0b215fa-78eb-44ad-9fdb-08924ff64132 + Vatin_1: + maxLength: 12 + minLength: 12 + pattern: "^(([0-9]{10})|([0-9]{12}))?$" + type: string + description: ИНН самозанятого + example: "112233445566" + CreatePoaResponse: + required: + - requestUuid + type: object + properties: + requestUuid: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Уникальный идентификатор запроса + example: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + description: Ответ на создание запроса выгрузки МЧД + example: + requestUuid: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + requestUuid: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Уникальный идентификатор запроса + example: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + ErrorBadRequest_3: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_request + error_description: + type: string + description: | + Возможные описания ошибки: + * `Authorization header is not present in request headers` - Неверные входные параметры запроса; + * `INN size must be between 10 and 15` - Неверная длина номера ИНН; + * `Invalid UUID string` - Неверный формат номера МЧД; + example: Invalid UUID string + enum: + - Authorization header is not present in request headers + - INN size must be between 10 and 15 + - Invalid UUID string + description: Неверные входные параметры запроса + GetPoaRequestStatusResponse: + required: + - detailedPoa + - downloadingStatus + - requestUuid + type: object + properties: + requestUuid: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Уникальный идентификатор запроса + example: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + downloadingStatus: + type: string + description: | + Статус запроса: + * `PENDING` - Незавершенный; + * `FAILED` - Неудачный; + * `TIMEOUT` - Превысил время ожидания; + * `COMPLETE` - Завершенный. + example: COMPLETE + enum: + - PENDING + - FAILED + - TIMEOUT + - COMPLETE + detailedPoa: + $ref: '#/components/schemas/DetailedPoa' + description: Ответ на получение статуса запроса выгрузки МЧД + example: + requestUuid: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + detailedPoa: + number: e0b215fa-78eb-44ad-9fdb-08924ff64132 + inn: "112233445566" + downloadingStatus: COMPLETE + DetailedPoa: + required: + - inn + - number + type: object + properties: + number: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Номер МЧД + example: e0b215fa-78eb-44ad-9fdb-08924ff64132 + inn: + maxLength: 12 + minLength: 12 + pattern: "^(([0-9]{10})|([0-9]{12}))?$" + type: string + description: ИНН самозанятого + example: "112233445566" + description: Информация о МЧД + example: + number: e0b215fa-78eb-44ad-9fdb-08924ff64132 + inn: "112233445566" + RequestPoaNotFound: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: entity_not_found + error_description: + type: string + example: Detail POA with requestUuid=3e2af6ad-2eee-4687-a391-eb07ebfc0719 + was not found. + description: Идентификатор запроса для получения детальной МЧД не найден + RequestDownloadError: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: entity_not_found + error_description: + type: string + description: | + Возможные описания ошибки: + * `Request(UUID: b15b88b2-b646-4ee6-b537-46e73d0b969d) for retrieving detailed POA not found` - requestUuid не найден; + * `Poa file path not found, historyId: 4077, format: ZIP` - requestUuid не в статусе "Complete" + example: "Request(UUID: b15b88b2-b646-4ee6-b537-46e73d0b969d) for retrieving\ + \ detailed POA not found" + enum: + - "Request(UUID: b15b88b2-b646-4ee6-b537-46e73d0b969d) for retrieving detailed\ + \ POA not found" + - "Poa file path not found, historyId: 4077, format: ZIP" + description: Идентификатор запроса для выгрузки МЧД не найден + GetPoaStatusResponse: + required: + - endDate + - id + - issuerPublicKey + - poaNumber + - startDate + - status + type: object + properties: + id: + type: string + description: Хеш доверенности + poaNumber: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Номер МЧД + example: e0b215fa-78eb-44ad-9fdb-08924ff64132 + startDate: + type: string + description: Дата начала действия доверенности + format: date + endDate: + type: string + description: Дата завершения действия доверенности + format: date + status: + type: string + description: | + Статус доверенности: + * `ACTIVE` - Активна; + * `EXPIRED` - Истекла; + * `REVOKED` - Аннулирована. + issuerPublicKey: + type: string + description: Публичный ключ эмитента доверенности + description: Ответ на запрос статуса МЧД + example: + endDate: 2000-01-23 + poaNumber: e0b215fa-78eb-44ad-9fdb-08924ff64132 + issuerPublicKey: issuerPublicKey + id: id + startDate: 2000-01-23 + status: status + PoaNotFound: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: entity_not_found + error_description: + type: string + example: Power of attorney with number e0b215fa-78eb-44ad-9fdb-08924ff64132 + not found. + description: Номер МЧД не найден + GetAccounts: + type: array + items: + $ref: '#/components/schemas/GetAccounts_inner' + UUID_2: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + RequestResponse: + required: + - requestId + - status + type: object + properties: + requestId: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: + $ref: '#/components/schemas/RequestStatus' + example: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: null + RequestStatus: + type: string + description: | + Статус запроса: + * `PENDING` - запрос в процессе обработки; + * `FAILED` - обработка запроса завершилась ошибкой; + * `COMPLETE` - обработка запроса завершилась успешно. + enum: + - PENDING + - FAILED + - COMPLETE + BeneficiaryType: + type: string + description: | + Тип бенефициара: + * `FL_RESIDENT` - Физ. лицо, резидент; + * `UL_RESIDENT` - Юр. лицо, резидент. + enum: + - FL_RESIDENT + - UL_RESIDENT + Date: + type: string + description: Дата + format: date + example: 2024-01-01 + BeneficiaryListResponse: + anyOf: + - $ref: '#/components/schemas/BeneficiaryFlResidentResponse' + - $ref: '#/components/schemas/BeneficiaryUlResidentResponse' + BeneficiaryFlResidentResponse: + required: + - accountNumber + - addresses + - beneficiaryId + - documents + - isActive + - isBeneficiary + - isVpr + - personalInformation + - type + type: object + properties: + beneficiaryId: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + isBeneficiary: + type: boolean + description: | + Признак бенефициара: + * `true` - является бенефициаром; + * `false` - является универсальным реципиентом. + isVpr: + type: boolean + description: | + Признак ВПР: + * `true` - является выгодоприобретателем; + * `false` - не является выгодоприобретателем. + type: + $ref: '#/components/schemas/BeneficiaryType' + personalInformation: + $ref: '#/components/schemas/PersonalInformation_2' + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + minItems: 1 + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + documents: + minItems: 1 + type: array + description: Документы + items: + $ref: '#/components/schemas/Passport_1' + isActive: + type: boolean + description: | + Признак активности бенефициара: + * `true` - активен; + * `false` - деактивирован. + PersonalInformation_2: + required: + - citizenship + - firstName + - lastName + - snils + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН + example: "112233445566" + firstName: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Имя + example: Иван + middleName: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Отчество + example: Иванoвич + lastName: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Фамилия + example: Иванов + citizenship: + $ref: '#/components/schemas/Citizenship_1' + birthDate: + type: string + description: Дата + format: date + example: 2024-01-01 + birthPlace: + maxLength: 128 + minLength: 1 + type: string + description: Место рождения + example: Г. Иркутск + snils: + pattern: "^(\\d{11})$" + type: string + description: СНИЛС + description: Персональные данные + Citizenship_1: + type: string + description: | + Гражданство: + * `RU` - РФ + enum: + - RU + PhoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + Email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + Address_1: + required: + - address + - type + type: object + properties: + type: + type: string + description: | + Тип адреса: + * `REGISTRATION_ADDRESS` - адрес регистрации; + * `LEGAL_ENTITY_ADDRESS` - адрес Юр.лица. + enum: + - REGISTRATION_ADDRESS + - LEGAL_ENTITY_ADDRESS + address: + type: string + description: Адрес + description: Адрес бенефициара + Passport_1: + required: + - division + - issueDate + - number + - organization + - serial + - type + type: object + properties: + type: + $ref: '#/components/schemas/DocumentType' + serial: + pattern: "^\\d{4}$" + type: string + description: Серия паспорта РФ + example: "6953" + number: + pattern: "^\\d{6}$" + type: string + description: Номер паспорта РФ + example: "987435" + issueDate: + type: string + description: Дата + format: date + example: 2024-01-01 + division: + pattern: "^\\d{3}-\\d{3}$" + type: string + description: "Код подразделения, выдавшего паспорт" + example: 123-321 + organization: + maxLength: 128 + minLength: 1 + type: string + description: "Орган, выдавший документ" + example: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + description: Паспорт гражданина РФ. Передается если `citizenship` равен `RU` + DocumentType: + type: string + description: Тип документа + enum: + - PASSPORT + BeneficiaryUlResidentResponse: + required: + - accountNumber + - addresses + - beneficiaryId + - isActive + - isBeneficiary + - isVpr + - name + - ogrn + - registrationDate + - type + - vatin + type: object + properties: + beneficiaryId: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + isBeneficiary: + type: boolean + description: | + Признак бенефициара: + * `true` - является бенефициаром; + * `false` - является универсальным реципиентом. + isVpr: + type: boolean + description: | + Признак ВПР: + * `true` - является выгодоприобретателем; + * `false` - не является выгодоприобретателем. + type: + $ref: '#/components/schemas/BeneficiaryType' + name: + type: string + description: Наименование организации + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + registrationDate: + type: string + description: Дата + format: date + example: 2024-01-01 + vatin: + pattern: "^(\\d{10})$" + type: string + description: ИНН + ogrn: + pattern: "^(\\d{13})$" + type: string + description: Основной государственный регистрационный номер + isActive: + type: boolean + description: | + Признак активности бенефициара: + * `true` - активен; + * `false` - деактивирован. + BeneficiaryRequest: + oneOf: + - $ref: '#/components/schemas/BeneficiaryFlResidentRequest' + - $ref: '#/components/schemas/BeneficiaryUlResidentRequest' + BeneficiaryFlResidentRequest: + required: + - accountNumber + - digestSignatures + - isBeneficiary + - type + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + isBeneficiary: + type: boolean + description: | + Признак бенефициара: + * `true` - является бенефициаром; + * `false` - является универсальным реципиентом. + type: + $ref: '#/components/schemas/BeneficiaryType' + personalInformation: + $ref: '#/components/schemas/PersonalInformation_2' + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + minItems: 1 + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + documents: + minItems: 1 + type: array + description: Документы + items: + $ref: '#/components/schemas/Passport_1' + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + DigestSignatures_2: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + BeneficiaryUlResidentRequest: + required: + - accountNumber + - digestSignatures + - isBeneficiary + - type + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + isBeneficiary: + type: boolean + description: | + Признак бенефициара: + * `true` - является бенефициаром; + * `false` - является универсальным реципиентом. + type: + $ref: '#/components/schemas/BeneficiaryType' + name: + type: string + description: Наименование организации + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + registrationDate: + type: string + description: Дата + format: date + example: 2024-01-01 + vatin: + pattern: "^(\\d{10})$" + type: string + description: ИНН + ogrn: + pattern: "^(\\d{13})$" + type: string + description: Основной государственный регистрационный + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + BeneficiaryResponse: + oneOf: + - $ref: '#/components/schemas/BeneficiaryFlResidentResponse' + - $ref: '#/components/schemas/BeneficiaryUlResidentResponse' + ChangeBeneficiaryRequest: + oneOf: + - $ref: '#/components/schemas/ChangeBeneficiaryFlResidentRequest' + - $ref: '#/components/schemas/ChangeBeneficiaryUlResidentRequest' + ChangeBeneficiaryFlResidentRequest: + required: + - digestSignatures + - type + type: object + properties: + type: + $ref: '#/components/schemas/BeneficiaryType' + personalInformation: + $ref: '#/components/schemas/EditablePersonalInformation' + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + minItems: 1 + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + documents: + minItems: 1 + type: array + description: Документы + items: + $ref: '#/components/schemas/Passport_1' + isActive: + type: boolean + description: Признак активности бенефициара + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + EditablePersonalInformation: + type: object + properties: + firstName: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Имя + example: Иван + middleName: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Отчество + example: Иванoвич + lastName: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+][^0-9!\\@#$%^&*()_+=\\[\\]{};':\"~`±§\\\\|,.<>\\\ + /\\n\\t?a-zA-Z]*$" + type: string + description: Фамилия + example: Иванов + birthDate: + type: string + description: Дата + format: date + example: 2024-01-01 + birthPlace: + maxLength: 128 + minLength: 1 + type: string + description: Место рождения + example: Г. Иркутск + ChangeBeneficiaryUlResidentRequest: + required: + - digestSignatures + - type + type: object + properties: + type: + $ref: '#/components/schemas/BeneficiaryType' + name: + type: string + description: Наименование организации + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + email: + maxLength: 136 + minLength: 6 + pattern: "^[a-zA-Z0-9_\\-\\.]{1,64}@[a-zA-Z0-9_-]{1,64}\\.[a-zA-Z]{2,6}$" + type: string + description: Адрес электронной почты + example: IvanovIvan@mail.ru + addresses: + type: array + description: Адреса + items: + $ref: '#/components/schemas/Address_1' + registrationDate: + type: string + description: Дата + format: date + example: 2024-01-01 + isActive: + type: boolean + description: Признак активности бенефициара + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + RequisiteRequest: + oneOf: + - $ref: '#/components/schemas/AccountRequest' + - $ref: '#/components/schemas/PhoneRequest' + - $ref: '#/components/schemas/PanRequest' + AccountRequest: + required: + - accountNumber + - bik + - digestSignatures + - type + type: object + properties: + type: + $ref: '#/components/schemas/RequisiteType' + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + bik: + pattern: "^([0-9]{9})$" + type: string + description: БИК банка + example: "044525593" + isMain: + type: boolean + description: "Признак основного платежных реквизитов бенефициара. По умо\ + лчанию для первых добавленных реквизитов — `true`, для следующих — `false`." + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + RequisiteType: + type: string + description: "Тип платежного реквизита: * `ACCOUNT_NUMBER` - реквизиты счета\ + ; * `CARD_NUMBER` - номер карты (токен); * `PHONE_NUMBER` - номер телефона\ + ." + enum: + - ACCOUNT_NUMBER + - PHONE_NUMBER + - CARD_NUMBER + Bik: + pattern: "^([0-9]{9})$" + type: string + description: БИК банка + example: "044525593" + PhoneRequest: + required: + - digestSignatures + - phoneNumber + - type + type: object + properties: + type: + $ref: '#/components/schemas/RequisiteType' + phoneNumber: + pattern: "^(\\79)([0-9]{9})$" + type: string + description: Телефон + example: "79130000011" + isMain: + type: boolean + description: "Признак основного платежных реквизитов бенефициара. По умо\ + лчанию для первых добавленных реквизитов — `true`, для следующих — `false`." + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + PanRequest: + required: + - pan + - type + type: object + properties: + type: + $ref: '#/components/schemas/RequisiteType' + pan: + type: string + description: Токен номера карты + example: wS7fElYo8VWeJ8KelaJ0XA== + isMain: + type: boolean + description: "Признак основного платежных реквизитов бенефициара. По умо\ + лчанию для первых добавленных реквизитов — `true`, для следующих — `false`." + digestSignatures: + maxItems: 10 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/DigestSignatures_2_inner' + PanNumber: + type: string + description: Токен номера карты + example: wS7fElYo8VWeJ8KelaJ0XA== + RequisiteResponse: + oneOf: + - $ref: '#/components/schemas/AccountResponse_1' + - $ref: '#/components/schemas/PhoneResponse' + - $ref: '#/components/schemas/PanResponse' + AccountResponse_1: + required: + - id + - isActive + - isMain + type: object + properties: + id: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + isMain: + type: boolean + description: | + Признак основных реквизитов: + * `true` - основные; + * `false` - не основные. + isActive: + type: boolean + description: | + Признак активности реквизитов: + * `true` - активны; + * `false` - деактивированы. + PhoneResponse: + required: + - id + - isActive + - isMain + type: object + properties: + id: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + isMain: + type: boolean + description: | + Признак основных реквизитов: + * `true` - основные; + * `false` - не основные. + isActive: + type: boolean + description: | + Признак активности реквизитов: + * `true` - активны; + * `false` - деактивированы. + PanResponse: + required: + - id + - isActive + - isMain + type: object + properties: + id: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + isMain: + type: boolean + description: | + Признак основных реквизитов: + * `true` - основные; + * `false` - не основные. + isActive: + type: boolean + description: | + Признак активности реквизитов: + * `true` - активны; + * `false` - деактивированы. + RequisiteSignRequest: + type: object + properties: + isMain: + type: boolean + description: | + Признак основных реквизитов: + * `true` - основные; + * `false` - не основные. + isActive: + type: boolean + description: | + Признак активности реквизитов: + * `true` - активны; + * `false` - деактивированы. + example: + isMain: true + isActive: true + BalanceResponse: + required: + - accountNumber + - balance + - beneficiaryId + - date + type: object + properties: + beneficiaryId: + type: string + description: Уникальный идентификатор + format: uuid + example: ab9cbb96-360a-4462-a683-955cc29f7f54 + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + date: + type: string + description: Дата + format: date + example: 2024-01-01 + balance: + type: string + description: Сумма + example: "10.00" + example: + date: 2024-01-01T00:00:00.000+00:00 + balance: "10.00" + accountNumber: "40817810306050000000" + beneficiaryId: ab9cbb96-360a-4462-a683-955cc29f7f54 + Amount_1: + type: string + description: Сумма + example: "10.00" + Accounts_1: + title: Счета + required: + - accounts + type: object + properties: + accounts: + title: Массив счетов + type: array + items: + $ref: '#/components/schemas/Account_2' + default: [] + example: + accounts: + - number: number + dateCreated: 2000-01-23 + balance: + amount: 1 + holds: 6 + currency: currency + minorUnits: 0 + mnemonic: mnemonic + typeDescription: typeDescription + type: type + status: null + - number: number + dateCreated: 2000-01-23 + balance: + amount: 1 + holds: 6 + currency: currency + minorUnits: 0 + mnemonic: mnemonic + typeDescription: typeDescription + type: type + status: null + Account_2: + title: Объект счёта + required: + - balance + - dateCreated + - mnemonic + - number + - status + - type + type: object + properties: + mnemonic: + type: string + description: Наименование счёта + number: + type: string + description: Номер счёта + type: + type: string + description: Тип счёта + typeDescription: + type: string + description: Описание типа счёта + status: + $ref: '#/components/schemas/AccountStatus_1' + dateCreated: + type: string + description: Дата открытия счёта + format: date + balance: + $ref: '#/components/schemas/AccountBalance' + example: + number: number + dateCreated: 2000-01-23 + balance: + amount: 1 + holds: 6 + currency: currency + minorUnits: 0 + mnemonic: mnemonic + typeDescription: typeDescription + type: type + status: null + AccountStatus_1: + title: Статус счёта + type: string + enum: + - ACTIVE + - INACTIVE + AccountBalance: + title: Баланс счёта + required: + - amount + - currency + - holds + - minorUnits + type: object + properties: + currency: + type: string + description: Валюта счёта (ISO 4217 Code) + minorUnits: + type: integer + description: Количество минорных единиц + holds: + type: integer + description: Сумма холдов (резервов) в минорных единицах + format: int64 + amount: + type: integer + description: Сумма денежных средств в минорных единицах + format: int64 + example: + amount: 1 + holds: 6 + currency: currency + minorUnits: 0 + AccountRequisites: + title: Реквизиты счёта + required: + - accountNumber + - bankName + - clientInfo + type: object + properties: + clientInfo: + $ref: '#/components/schemas/ClientInfo_1' + accountNumber: + type: string + description: Номер счёта клиента + bankName: + type: string + description: Полное наименование Банка + bic: + type: string + description: БИК Банка + inn: + type: string + description: ИНН Банка + kpp: + type: string + description: КПП Банка + swift: + type: string + description: SWIFT код Банка + correspondentAccountNumber: + type: string + description: Корреспондентский счёт + correspondentBanks: + type: array + description: Массив банков-корреспондентов (для SWIFT переводов) + items: + $ref: '#/components/schemas/CorrespondentBank' + example: + correspondentBanks: + - correspondentBankAccountNumber: correspondentBankAccountNumber + correspondentBankName: correspondentBankName + correspondentSwift: correspondentSwift + - correspondentBankAccountNumber: correspondentBankAccountNumber + correspondentBankName: correspondentBankName + correspondentSwift: correspondentSwift + inn: inn + correspondentAccountNumber: correspondentAccountNumber + clientInfo: + translitFirstName: translitFirstName + firstName: firstName + lastName: lastName + translitPatronymicName: translitPatronymicName + patronymicName: patronymicName + translitLastName: translitLastName + bankName: bankName + kpp: kpp + accountNumber: accountNumber + bic: bic + swift: swift + ClientInfo_1: + title: Информация по клиенту + required: + - firstName + - lastName + type: object + properties: + firstName: + type: string + description: Имя + lastName: + type: string + description: Фамилия + patronymicName: + type: string + description: Отчество + translitFirstName: + type: string + description: Транслитерация имени (для валютных счетов) + translitLastName: + type: string + description: Транслитерация фамилии (для валютных счетов) + translitPatronymicName: + type: string + description: Транслитерация отчества (для валютных счетов) + example: + translitFirstName: translitFirstName + firstName: firstName + lastName: lastName + translitPatronymicName: translitPatronymicName + patronymicName: patronymicName + translitLastName: translitLastName + CorrespondentBank: + title: Банк-корреспондент + required: + - correspondentBankAccountNumber + - correspondentSwift + type: object + properties: + correspondentBankAccountNumber: + type: string + description: Номер счёта в Банке-корреспонденте + correspondentBankName: + type: string + description: Полное наименование Банка-корреспондента + correspondentSwift: + type: string + description: SWIFT-код Банка-корреспондента + example: + correspondentBankAccountNumber: correspondentBankAccountNumber + correspondentBankName: correspondentBankName + correspondentSwift: correspondentSwift + Cards: + title: Карты + required: + - cards + type: object + properties: + cards: + title: Массив карт + type: array + items: + $ref: '#/components/schemas/Card' + default: [] + example: + cards: + - paymentSystem: paymentSystem + typeDescription: typeDescription + type: type + title: title + isCredit: true + maskedNumber: maskedNumber + isPrimary: true + cardId: cardId + isVirtual: true + state: + isClosed: true + isBlocked: true + isActive: true + isPinInstalled: true + issueDate: 2000-01-23 + account: + number: number + status: status + expirationDate: expirationDate + - paymentSystem: paymentSystem + typeDescription: typeDescription + type: type + title: title + isCredit: true + maskedNumber: maskedNumber + isPrimary: true + cardId: cardId + isVirtual: true + state: + isClosed: true + isBlocked: true + isActive: true + isPinInstalled: true + issueDate: 2000-01-23 + account: + number: number + status: status + expirationDate: expirationDate + Card: + title: Объект карты + required: + - account + - cardId + - expirationDate + - isCredit + - isPrimary + - isVirtual + - issueDate + - maskedNumber + - paymentSystem + - state + - status + - type + - typeDescription + type: object + properties: + cardId: + type: string + description: Идентификатор карты + maskedNumber: + type: string + description: Маскированный номер карты + type: + type: string + description: Тип карты + typeDescription: + type: string + description: Тип продукта карты + status: + type: string + description: Статус карты + issueDate: + type: string + description: Дата выпуска карты + format: date + expirationDate: + type: string + description: Срок действия карты + format: year-month + title: + type: string + description: Наименование карты + isPrimary: + type: boolean + description: Признак основной карты + isVirtual: + type: boolean + description: Признак виртуальной карты + isCredit: + type: boolean + description: Признак кредитной карты + account: + $ref: '#/components/schemas/CardAccount' + paymentSystem: + type: string + state: + $ref: '#/components/schemas/CardState' + example: + paymentSystem: paymentSystem + typeDescription: typeDescription + type: type + title: title + isCredit: true + maskedNumber: maskedNumber + isPrimary: true + cardId: cardId + isVirtual: true + state: + isClosed: true + isBlocked: true + isActive: true + isPinInstalled: true + issueDate: 2000-01-23 + account: + number: number + status: status + expirationDate: expirationDate + CardAccount: + title: Счет карты + required: + - number + type: object + properties: + number: + type: string + description: Номер счёта к которому привязана карта + example: + number: number + CardState: + type: object + properties: + isActive: + type: boolean + isBlocked: + type: boolean + isClosed: + type: boolean + isPinInstalled: + type: boolean + example: + isClosed: true + isBlocked: true + isActive: true + isPinInstalled: true + CardActions: + required: + - actions + type: object + properties: + actions: + type: array + items: + $ref: '#/components/schemas/CardAction' + default: [] + example: + actions: + - available: true + actionId: null + title: title + - available: true + actionId: null + title: title + CardAction: + required: + - actionId + type: object + properties: + actionId: + $ref: '#/components/schemas/CardActionId' + title: + type: string + available: + type: boolean + example: + available: true + actionId: null + title: title + CardActionId: + type: string + enum: + - CARD_BLOCK + - CARD_UNBLOCK + - CARD_PIN_CHANGE + CardActionConfirmBody: + required: + - actionId + - password + - reference + type: object + properties: + actionId: + $ref: '#/components/schemas/CardActionId' + password: + type: string + reference: + type: string + example: + reference: reference + password: password + actionId: null + CardActionCreateBody: + required: + - actionId + type: object + properties: + actionId: + $ref: '#/components/schemas/CardActionId' + example: + actionId: null + CardActionCreateResponse: + required: + - auth + - passwordLength + - reference + type: object + properties: + reference: + type: string + auth: + $ref: '#/components/schemas/BlockActionConfirmationType' + passwordLength: + type: integer + example: + reference: reference + auth: null + passwordLength: 0 + BlockActionConfirmationType: + type: string + enum: + - SMSPWD + - AM + Tariffs: + title: Тарифы по карте + required: + - conditions + type: object + properties: + conditions: + $ref: '#/components/schemas/CardConditions' + example: + conditions: + isSalaryCard: true + isCombo: true + cardServiceFee: + fee: 0.8008281904610115 + feePeriod: null + CardConditions: + title: Условия обслуживания по карте + required: + - cardServiceFee + type: object + properties: + cardServiceFee: + $ref: '#/components/schemas/CardServiceFee' + isSalaryCard: + type: boolean + description: Признак зарплатной карты + isCombo: + type: boolean + description: Признак комбинированной карты + example: + isSalaryCard: true + isCombo: true + cardServiceFee: + fee: 0.8008281904610115 + feePeriod: null + CardServiceFee: + title: Комиссия за обслуживание + required: + - fee + - feePeriod + type: object + properties: + fee: + type: number + description: Размер комиссии + feePeriod: + $ref: '#/components/schemas/FeePeriod' + example: + fee: 0.8008281904610115 + feePeriod: null + FeePeriod: + title: Тип комиссии за обслуживание + type: string + enum: + - MONTHLY + - YEARLY + Subscriptions: + title: Уведомления по операциям + required: + - subscriptionCard + - subscriptionTariffs + type: object + properties: + subscriptionCard: + $ref: '#/components/schemas/SubscriptionCard' + subscriptionTariffs: + title: Список тарифов на услугу Альфа-чек доступных пользователю + type: array + items: + $ref: '#/components/schemas/SubscriptionTariff' + default: [] + example: + subscriptionCard: + type: type + ips: ips + subscriptionTariffs: + - isContactPhoneRequired: true + name: name + isSelected: true + id: id + priceAmount: "{}" + - isContactPhoneRequired: true + name: name + isSelected: true + id: id + priceAmount: "{}" + SubscriptionCard: + title: Информация о карте + required: + - ips + - type + type: object + properties: + ips: + type: string + description: Название карты в рамках ips (международной системы платежей) + type: + type: string + description: Тип карты + example: + type: type + ips: ips + SubscriptionTariffs: + title: Список тарифов на услугу Альфа-чек доступных пользователю + type: array + items: + $ref: '#/components/schemas/SubscriptionTariff' + default: [] + SubscriptionTariff: + title: Тариф на услугу Альфа-чек + required: + - id + - isContactPhoneRequired + - isSelected + - name + type: object + properties: + id: + type: string + description: Идентификатор тарифа + name: + type: string + description: Наименование тарифа + priceAmount: + title: Стоимость тарифа + type: object + format: commons.Amount + isSelected: + type: boolean + description: Признак выбора тарифа + isContactPhoneRequired: + type: boolean + description: Признак необходимости указания номера телефона + example: + isContactPhoneRequired: true + name: name + isSelected: true + id: id + priceAmount: "{}" + OperationsHistory: + title: История операций + required: + - operations + type: object + properties: + operations: + title: Массив операций + type: array + items: + $ref: '#/components/schemas/OperationHistoryItem' + default: [] + example: + operations: + - dateTime: 2000-01-23T04:56:07.000+00:00 + amount: "{}" + loyalty: + amount: "{}" + title: title + percent: 0.8008281904610115 + fee: 6.027456183070403 + isAnotherClient: false + terminal: + number: number + city: city + countryCode: countryCode + name: name + title: title + mcc: mcc + type: type + cashout: false + reference: reference + sender: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + accountNumber: accountNumber + maskedCardNumber: maskedCardNumber + recipient: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + comment: comment + id: id + category: + name: name + id: id + direction: null + status: null + - dateTime: 2000-01-23T04:56:07.000+00:00 + amount: "{}" + loyalty: + amount: "{}" + title: title + percent: 0.8008281904610115 + fee: 6.027456183070403 + isAnotherClient: false + terminal: + number: number + city: city + countryCode: countryCode + name: name + title: title + mcc: mcc + type: type + cashout: false + reference: reference + sender: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + accountNumber: accountNumber + maskedCardNumber: maskedCardNumber + recipient: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + comment: comment + id: id + category: + name: name + id: id + direction: null + status: null + OperationHistoryItem: + title: Объект с информацией по операции + required: + - amount + - cashout + - dateTime + - direction + - fee + - id + - isAnotherClient + - title + type: object + properties: + id: + type: string + description: Идентификатор операции + dateTime: + type: string + description: Дата и время операции + format: date-time + title: + type: string + description: Заголовок операции + amount: + title: Сумма операции + type: object + description: Сумма операции + format: commons.Amount + comment: + type: string + description: Комментарий к операции + mcc: + type: string + description: MCC код операции + category: + $ref: '#/components/schemas/OperationCategory' + direction: + $ref: '#/components/schemas/OperationDirection' + loyalty: + $ref: '#/components/schemas/OperationLoyalty' + status: + $ref: '#/components/schemas/OperationStatus' + type: + type: string + description: Тип операции + terminal: + $ref: '#/components/schemas/SellingPointTerminal' + sender: + $ref: '#/components/schemas/OperationSender' + recipient: + $ref: '#/components/schemas/OperationRecipient' + fee: + type: number + description: Комиссия по операции + reference: + type: string + description: Поле для связки сопоставления поля умной шины NIMB и сервиса + LOYALTY STATEMENT API + isAnotherClient: + type: boolean + description: "Признак того, что операция выполнена другим клиентом" + default: false + cashout: + type: boolean + description: Признак снятия наличности в банкомате + default: false + example: + dateTime: 2000-01-23T04:56:07.000+00:00 + amount: "{}" + loyalty: + amount: "{}" + title: title + percent: 0.8008281904610115 + fee: 6.027456183070403 + isAnotherClient: false + terminal: + number: number + city: city + countryCode: countryCode + name: name + title: title + mcc: mcc + type: type + cashout: false + reference: reference + sender: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + accountNumber: accountNumber + maskedCardNumber: maskedCardNumber + recipient: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + comment: comment + id: id + category: + name: name + id: id + direction: null + status: null + OperationCategory: + title: Объект программы лояльности + required: + - id + - name + type: object + properties: + id: + type: string + description: Идентификатор категории + name: + type: string + description: Наименование категории + example: + name: name + id: id + OperationDirection: + title: Направление движения денежных средств + type: string + description: "Направление движения денежных средств: INCOME - приход/пополне\ + ние, EXPENSE - расход/списание" + enum: + - EXPENSE + - INCOME + OperationLoyalty: + title: Объект программы лояльности + type: object + properties: + title: + type: string + description: Заголовок бонусной программы / программы лояльности + percent: + type: number + description: Процент от суммы + amount: + title: Сумма по программе + type: object + description: Сумма по программе + format: commons.Amount + example: + amount: "{}" + title: title + percent: 0.8008281904610115 + OperationStatus: + title: Статус операции + type: string + description: "Статус операции: null - входящая операция или статус не опреде\ + лен SUCCESS - операция выполнена успешна HOLD - операция в обработке FAILED\ + \ - операция не выполнена" + enum: + - HOLD + - SUCCESS + - FAILED + SellingPointTerminal: + title: Объект терминал точки продаж + type: object + properties: + number: + type: string + description: Номер терминала точки продаж + name: + type: string + description: Имя точки продаж + city: + type: string + description: Город точки продаж (код) + countryCode: + type: string + description: Страна точки продаж (код) + example: + number: number + city: city + countryCode: countryCode + name: name + OperationSender: + title: Объект отправитель перевода + type: object + properties: + name: + type: string + description: Отправитель перевода + accountNumber: + type: string + description: Номер счёта отправителья перевода / клиента + bankBik: + type: string + description: БИК банка отправителя + bankName: + type: string + description: Название банка отправителя + phoneNumber: + type: string + description: Номер телефона отправителя + maskedCardNumber: + type: string + description: Номер карты (маскированный) отправителя + example: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + accountNumber: accountNumber + maskedCardNumber: maskedCardNumber + OperationRecipient: + title: Объект получатель перевода + type: object + properties: + name: + type: string + description: Получатель перевода + bankBik: + type: string + description: БИК банка получателя + bankName: + type: string + description: Название банка получателя + phoneNumber: + type: string + description: Номер телефона получателя + example: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + OperationDetails: + title: Объект с информацией по операции + required: + - amount + - cashout + - dateTime + - direction + - fee + - id + - isAnotherClient + - title + type: object + properties: + id: + type: string + description: Идентификатор операции + dateTime: + type: string + description: Дата и время операции + format: date-time + title: + type: string + description: Заголовок операции + amount: + title: Сумма операции + type: object + description: Сумма операции + format: commons.Amount + comment: + type: string + description: Комментарий к операции + mcc: + type: string + description: MCC код операции + category: + $ref: '#/components/schemas/OperationCategory' + direction: + $ref: '#/components/schemas/OperationDirection' + loyalty: + $ref: '#/components/schemas/OperationLoyalty' + status: + $ref: '#/components/schemas/OperationStatus' + type: + type: string + description: Тип операции + terminal: + $ref: '#/components/schemas/SellingPointTerminal' + sender: + $ref: '#/components/schemas/OperationSender' + recipient: + $ref: '#/components/schemas/OperationRecipient' + fee: + type: number + description: Комиссия по операции + reference: + type: string + description: Поле для связки сопоставления поля умной шины NIMB и сервиса + LOYALTY STATEMENT API + isAnotherClient: + type: boolean + description: "Признак того, что операция выполнена другим клиентом" + default: false + cashout: + type: boolean + description: Признак снятия наличности в банкомате + default: false + example: + dateTime: 2000-01-23T04:56:07.000+00:00 + amount: "{}" + loyalty: + amount: "{}" + title: title + percent: 0.8008281904610115 + fee: 0.8008281904610115 + isAnotherClient: false + terminal: + number: number + city: city + countryCode: countryCode + name: name + title: title + mcc: mcc + type: type + cashout: false + reference: reference + sender: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + accountNumber: accountNumber + maskedCardNumber: maskedCardNumber + recipient: + bankBik: bankBik + phoneNumber: phoneNumber + name: name + bankName: bankName + comment: comment + id: id + category: + name: name + id: id + direction: null + status: null + AccountReportRequest: + required: + - accountIds + - dateBegin + - dateEnd + type: object + properties: + accountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + dateBegin: + type: string + format: date + dateEnd: + type: string + format: date + example: + dateBegin: 2000-01-23 + accountIds: + - accountIds + - accountIds + dateEnd: 2000-01-23 + AccountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + Report: + required: + - date + - id + - status + - type + type: object + properties: + id: + type: string + description: Идентификатор отчета + example: 62c4f39c5f1503000128a5e2 + date: + type: string + description: Дата формирования объекта заказа + format: date-time + type: + $ref: '#/components/schemas/Report_type' + status: + $ref: '#/components/schemas/Report_status' + description: Объект справки + example: + date: 2000-01-23T04:56:07.000+00:00 + id: 62c4f39c5f1503000128a5e2 + type: + code: code + description: description + title: title + status: + code: NEW + title: title + CreditProductReportRequest: + required: + - accountIds + - dateBegin + - dateEnd + - operationsHistory + type: object + properties: + accountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + dateBegin: + type: string + format: date + dateEnd: + type: string + format: date + agreementNumber: + type: string + description: Номер кредитного договора + example: F0TCRC20S19031508353 + operationsHistory: + type: boolean + description: Детальная информация по депозиту + example: true + example: + dateBegin: 2000-01-23 + accountIds: + - accountIds + - accountIds + operationsHistory: true + dateEnd: 2000-01-23 + agreementNumber: F0TCRC20S19031508353 + AccountBalanceEngReportRequest: + required: + - accountIds + type: object + properties: + accountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + customNameTranscription: + type: string + example: + accountIds: + - accountIds + - accountIds + customNameTranscription: customNameTranscription + AccountBalanceRurReportRequest: + required: + - accountIds + type: object + properties: + accountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + example: + accountIds: + - accountIds + - accountIds + DepositReportRequest: + required: + - accountIds + type: object + properties: + accountIds: + type: array + description: "Массив выбранных счетов, по которым заказывается справка" + items: + type: string + default: [] + example: + accountIds: + - accountIds + - accountIds + Limits: + title: Лимиты + required: + - day + - month + - oneTime + type: object + properties: + oneTime: + type: object + additionalProperties: + $ref: '#/components/schemas/Section' + description: Единовременно + day: + type: object + additionalProperties: + $ref: '#/components/schemas/Section' + description: В день + month: + type: object + additionalProperties: + $ref: '#/components/schemas/Section' + description: В месяц + example: + month: + key: + title: title + limits: + key: + rest: "{}" + max: "{}" + isPersonal: true + title: title + type: null + turnover: "{}" + oneTime: + key: + title: title + limits: + key: + rest: "{}" + max: "{}" + isPersonal: true + title: title + type: null + turnover: "{}" + day: + key: + title: title + limits: + key: + rest: "{}" + max: "{}" + isPersonal: true + title: title + type: null + turnover: "{}" + Section: + title: Группа лимитов + required: + - limits + - title + type: object + properties: + title: + type: string + description: Название + limits: + type: object + additionalProperties: + $ref: '#/components/schemas/Limit' + example: + title: title + limits: + key: + rest: "{}" + max: "{}" + isPersonal: true + title: title + type: null + turnover: "{}" + Limit: + title: Лимит + required: + - isPersonal + - max + - rest + - title + - turnover + - type + type: object + properties: + title: + type: string + description: Название + max: + title: Максимум + type: object + format: commons-AmountDto + rest: + title: Остаток + type: object + format: commons-AmountDto + turnover: + title: Оборот + type: object + format: commons-AmountDto + type: + $ref: '#/components/schemas/LimitType' + isPersonal: + type: boolean + description: Признак персонального лимита + example: + rest: "{}" + max: "{}" + isPersonal: true + title: title + type: null + turnover: "{}" + LimitType: + title: Тип лимита + type: string + enum: + - UNLIMITED + - GENERAL + - NON_RENEWABLE + UserLimitsGetResponse: + required: + - limits + type: object + properties: + limits: + type: array + items: + $ref: '#/components/schemas/UserLimit' + example: + limits: + - null + - null + UserLimit: + allOf: + - $ref: '#/components/schemas/UserLimitSeed' + - $ref: '#/components/schemas/UserLimit_allOf' + UserLimitSeed: + type: object + properties: + activity: + $ref: '#/components/schemas/Activity' + validity: + $ref: '#/components/schemas/Validity' + coveredOperations: + type: array + items: + $ref: '#/components/schemas/CoveredOperation' + limits: + $ref: '#/components/schemas/LimitValues' + example: + activity: + from: 2000-01-23 + to: 2000-01-23 + coveredOperations: + - null + - null + validity: null + limits: + single: "{}" + rest: "{}" + max: "{}" + turnover: "{}" + Activity: + required: + - from + - to + type: object + properties: + from: + type: string + format: date + x-alfa-constraints: + jsonFormat: + pattern: dd-MM-yyyy + to: + type: string + format: date + x-alfa-constraints: + jsonFormat: + pattern: dd-MM-yyyy + example: + from: 2000-01-23 + to: 2000-01-23 + Validity: + type: string + enum: + - wholePeriod + - daily + - weekly + - monthly + CoveredOperations: + type: array + items: + $ref: '#/components/schemas/CoveredOperation' + CoveredOperation: + type: string + enum: + - allDebits + - onlineShopping + - cashWithdrawals + LimitValues: + required: + - max + - single + type: object + properties: + single: + type: object + format: commons-AmountDto + max: + type: object + format: commons-AmountDto + rest: + type: object + format: commons-AmountDto + turnover: + type: object + format: commons-AmountDto + description: "Значение на одну операцию,максимальное значение, остаток и обо\ + рот за период" + example: + single: "{}" + rest: "{}" + max: "{}" + turnover: "{}" + CountriesRestrictions: + type: object + properties: + restrictionType: + $ref: '#/components/schemas/RestrictionType' + list: + type: array + items: + $ref: '#/components/schemas/Country' + RestrictionType: + type: string + enum: + - all + - including + - excluding + Country: + type: object + properties: + isoCode: + type: string + description: + type: string + UserLimitId: + required: + - id + type: object + properties: + id: + type: integer + example: + id: 0 + LoyaltyAccount: + title: Бонусный счёт + required: + - accountNumber + - typeDescription + - typeId + type: object + properties: + accountNumber: + title: Номер бонусного счёта + type: string + typeId: + title: Идентификатор типа бонусного счёта + type: string + typeDescription: + title: Наименование/описание типа бонусного счёта + type: string + balanceAmount: + allOf: + - title: Баланс счёта + type: object + description: Баланс счёта + format: commons.Amount + example: + typeId: typeId + typeDescription: typeDescription + accountNumber: accountNumber + balanceAmount: "" + LoyaltyFilter: + title: Фильтр истории начислений + required: + - endDate + - references + - startDate + type: object + properties: + startDate: + title: Дата начала + type: string + format: date + endDate: + title: Дата окончания + type: string + format: date + references: + title: Массив референсов транзакций + type: array + items: + type: string + default: [] + example: + references: + - references + - references + endDate: 2000-01-23 + startDate: 2000-01-23 + LoyaltyTransaction: + title: Транзакция + required: + - account + - cashbackAmount + - title + type: object + properties: + title: + title: Наименование операции + type: string + account: + title: Номер счёта + type: string + reference: + title: Референс (идентификатор) операции + type: string + cashbackPercent: + title: Процент кэшбека + type: number + cashbackAmount: + allOf: + - title: Сумма бонуса + type: object + description: Сумма бонуса + format: commons.Amount + example: + reference: reference + cashbackAmount: "" + cashbackPercent: 0.8008281904610115 + title: title + account: account + AccountCashback: + title: Информация о начислениях по бонусному счету клиента + required: + - cashbackAccount + - cashbackForecast + - cashbackStatistic + - overallCashback + type: object + properties: + cashbackAccount: + $ref: '#/components/schemas/CashbackAccount' + cashbackForecast: + $ref: '#/components/schemas/CashbackForecast' + cashbackStatistic: + $ref: '#/components/schemas/CashbackStatistic' + overallCashback: + $ref: '#/components/schemas/OverallCashback' + example: + cashbackStatistic: + payments: + - period: period + amount: "" + status: null + - period: period + amount: "" + status: null + cashbackAccount: + typeId: typeId + typeDescription: typeDescription + accountNumber: accountNumber + balanceAmount: "" + overallCashback: + amount: "" + description: description + cashbackForecast: + totalIntermediatePeriodAmount: + payOutDate: 2000-01-23 + amount: "" + totalActivePeriodAmount: + payOutDate: 2000-01-23 + amount: "" + CashbackAccount: + title: Бонусный счёт + required: + - accountNumber + - typeDescription + - typeId + type: object + properties: + accountNumber: + title: Номер бонусного счёта + type: string + typeId: + title: Идентификатор типа бонусного счёта + type: string + typeDescription: + title: Наименование/описание типа бонусного счёта + type: string + balanceAmount: + allOf: + - title: Баланс счёта + type: object + description: Баланс счёта + format: commons.Amount + example: + typeId: typeId + typeDescription: typeDescription + accountNumber: accountNumber + balanceAmount: "" + CashbackForecast: + title: Прогноз начислений кешбэка + required: + - totalActivePeriodAmount + type: object + properties: + totalActivePeriodAmount: + $ref: '#/components/schemas/TotalActivePeriodAmount' + totalIntermediatePeriodAmount: + $ref: '#/components/schemas/TotalIntermediatePeriodAmount' + example: + totalIntermediatePeriodAmount: + payOutDate: 2000-01-23 + amount: "" + totalActivePeriodAmount: + payOutDate: 2000-01-23 + amount: "" + TotalActivePeriodAmount: + title: Кешбэк за текущий расчетный период + required: + - amount + - payOutDate + type: object + properties: + amount: + allOf: + - title: Кол-во начисленного кешбэка + type: object + description: Кол-во начисленного кешбэка + format: commons.Amount + payOutDate: + title: Дата начисления кешбэка + type: string + format: date + example: + payOutDate: 2000-01-23 + amount: "" + TotalIntermediatePeriodAmount: + title: Прогноз начисления кешбэка за следующий расчетный период + required: + - amount + - payOutDate + type: object + properties: + amount: + allOf: + - title: Кол-во начисленного кешбэка + type: object + description: Кол-во начисленного кешбэка + format: commons.Amount + payOutDate: + title: Дата начисления кешбэка + type: string + format: date + example: + payOutDate: 2000-01-23 + amount: "" + CashbackStatistic: + title: График начислений кешбэка + required: + - payments + type: object + properties: + payments: + title: Массив с графиком начислений + type: array + items: + $ref: '#/components/schemas/Payment_2' + default: [] + example: + payments: + - period: period + amount: "" + status: null + - period: period + amount: "" + status: null + Payment_2: + title: Объект графика начислений. Начисление кешбэка за указанный период. + required: + - amount + - period + - status + type: object + properties: + period: + title: Месяц и год периода + type: string + status: + $ref: '#/components/schemas/PaymentStatus_1' + amount: + allOf: + - title: Кол-во начисленного кешбэка + type: object + description: Кол-во начисленного кешбэка + format: commons.Amount + example: + period: period + amount: "" + status: null + PaymentStatus_1: + title: "Статус периода начисления: PAST (для предыдущих месяцев), PRESENT (д\ + ля текущего месяца)" + type: string + enum: + - PAST + - PRESENT + OverallCashback: + title: Общий кешбэк за все время + required: + - amount + - description + type: object + properties: + amount: + allOf: + - title: Кол-во начисленного кешбэка + type: object + description: Кол-во начисленного кешбэка + format: commons.Amount + description: + title: Период начисления кешбэка + type: string + example: + amount: "" + description: description + CreateFormRequest: + required: + - embossingName + - firstName + - lastName + - middleName + - mobilePhone + - passportBirthDate + - sex + - sopdConfirmed + type: object + properties: + embossingName: + type: string + description: Имя на дебетовой карте + example: PETROV IVAN + firstName: + type: string + description: Имя + example: Иван + lastName: + type: string + description: Фамилия + example: Петров + middleName: + type: string + description: Отчество + example: Викторович + mobilePhone: + type: string + description: Мобильный телефон + example: "9012345678" + email: + type: string + description: Адрес электронной почты + example: example@yandex.ru + passportBirthDate: + type: string + description: Дата рождения + format: date + example: 1990-09-15 + previousFormId: + type: string + description: formId предыдущей заявки (чтобы помечать её как удаленную) + example: AAAA16686C43888CE05CCCAC163B298F + sex: + type: string + description: Пол + enum: + - f + - m + sopdConfirmed: + type: boolean + description: Флаг согласия на обработку персональных данных + example: true + description: Данные для формирования заявки для заказа карты + example: + firstName: Иван + lastName: Петров + mobilePhone: "9012345678" + sex: f + passportBirthDate: 1990-09-15T00:00:00.000+00:00 + embossingName: PETROV IVAN + middleName: Викторович + sopdConfirmed: true + email: example@yandex.ru + previousFormId: AAAA16686C43888CE05CCCAC163B298F + CreateFormResponse: + required: + - formId + - status + type: object + properties: + formId: + type: string + description: Идентификатор заявки + example: 55A42D1698400C9EE0543863BB4C2866 + draftId: + type: string + description: Идентификатор черновика заявки + example: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + $ref: '#/components/schemas/DebitCardPayload' + productType: + type: string + description: Тип продукта + example: DC + status: + type: string + description: Статус-результат обработки заявки + example: APPROVAL_REJECT + description: Подтверждение получения данных заявки Банком + example: + formId: 55A42D1698400C9EE0543863BB4C2866 + draftId: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + requireCodeWord: true + userStatus: + - DT + - DT + cardId: RR + packageId: T04 + contractId: PDRR + cause: NOT_REQUESTED + subscription: "200" + url: https://testjmb.alfabank.ru/alfaform-dc-short-ui/draft?draftId=344101726FFB44BAB62DAFEC3824D0C0 + cashback: + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + productType: DC + status: APPROVAL_REJECT + DebitCardPayload: + type: object + properties: + cardId: + type: string + description: "Идентификатор карты, которую заказал пользователь" + example: RR + packageId: + type: string + description: Пакет услуг клиента + example: T04 + contractId: + type: string + description: Карточный контракт пользователя + example: PDRR + userStatus: + type: array + description: "Название клиентского пути. Принимает возможные значения: DT\ + \ - клиент ЦТ; NODT - действующий клиент, дополнительно может быть ука\ + зано FAMILY - клиент Семейного Банка" + items: + uniqueItems: true + type: string + enum: + - DT + - NODT + - FAMILY + url: + type: string + description: Ссылка на черновик заявки + example: https://testjmb.alfabank.ru/alfaform-dc-short-ui/draft?draftId=344101726FFB44BAB62DAFEC3824D0C0 + subscription: + type: string + description: Подписка (ответ МАПЛ) + example: "200" + cashback: + type: array + description: Список ответов МАПЛ на запрашиваемые категории кешбэка по месяцам + items: + $ref: '#/components/schemas/DebitCardCashback' + cause: + type: string + description: Дополнительные данные не запрашивались (ответ оркестратора) + example: NOT_REQUESTED + description: Дополнительная информация по запросу + example: + requireCodeWord: true + userStatus: + - DT + - DT + cardId: RR + packageId: T04 + contractId: PDRR + cause: NOT_REQUESTED + subscription: "200" + url: https://testjmb.alfabank.ru/alfaform-dc-short-ui/draft?draftId=344101726FFB44BAB62DAFEC3824D0C0 + cashback: + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + DebitCardCashback: + required: + - month + - status + type: object + properties: + month: + type: string + description: "Месяц, на который выбраны категории" + format: date + example: 2024-05-01 + status: + type: string + description: Статус ответа МАПЛа + example: "200" + example: + month: 2024-05-01T00:00:00.000+00:00 + status: "200" + ServiceError: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: invalid_request + error_description: + type: string + description: Сообщение об ошибке + example: "The request is missing a required parameter, includes an unsupported\ + \ parameter or parameter value, repeats the same parameter, uses more\ + \ than one method for including an access token, or is otherwise malformed" + description: Ошибка от сервиса + VerifyPassportRequest: + required: + - passportFullNumber + type: object + properties: + passportFullNumber: + type: string + description: Серия и номер паспорта + example: "4015678904" + description: Подтверждение паспортных данных + example: + passportFullNumber: "4015678904" + VerifyPassportResponse: + required: + - formId + - status + type: object + properties: + formId: + type: string + description: Идентификатор заявки + example: 55A42D1698400C9EE0543863BB4C2866 + draftId: + type: string + description: Идентификатор черновика заявки + example: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + $ref: '#/components/schemas/DebitCardPayload' + productType: + type: string + description: Тип продукта + example: DC + status: + type: string + description: Статус-результат обработки заявки + example: APPROVAL_REJECT + description: Паспортные данные получены Банком + example: + formId: 55A42D1698400C9EE0543863BB4C2866 + draftId: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + requireCodeWord: true + userStatus: + - DT + - DT + cardId: RR + packageId: T04 + contractId: PDRR + cause: NOT_REQUESTED + subscription: "200" + url: https://testjmb.alfabank.ru/alfaform-dc-short-ui/draft?draftId=344101726FFB44BAB62DAFEC3824D0C0 + cashback: + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + - month: 2024-05-01T00:00:00.000+00:00 + status: "200" + productType: DC + status: APPROVAL_REJECT + PhaseId: + type: string + description: Этап процесса + enum: + - CREATION + - COMPLETION + VerifySmsRequest: + required: + - smsCode + type: object + properties: + smsCode: + type: string + description: SMS-код для подтверждения действия + example: "41851" + description: Отправка SMS кода подтверждения + example: + smsCode: "41851" + VerifySmsFormCreationResponse: + required: + - formId + - status + type: object + properties: + formId: + type: string + description: Идентификатор заявки + example: 55A42D1698400C9EE0543863BB4C2866 + draftId: + type: string + description: Идентификатор черновика заявки + example: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + $ref: '#/components/schemas/DebitCardPayload' + productType: + type: string + description: Тип продукта + example: DC + status: + type: string + description: Статус-результат обработки заявки + example: SUCCESS + description: SMS код для подтверждения оформления заявки успешно получен Банком + VerifySmsFormCompletionResponse: + required: + - status + type: object + properties: + status: + type: string + description: Статус-результат обработки заявки + example: SUCCESS + description: SMS код для завершения оформления заявки успешно получен Банком + ResendSmsCreationResponse: + required: + - formId + - status + type: object + properties: + formId: + type: string + description: Идентификатор заявки + example: 55A42D1698400C9EE0543863BB4C2866 + draftId: + type: string + description: Идентификатор черновика заявки + example: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + $ref: '#/components/schemas/DebitCardPayload' + productType: + type: string + description: Тип продукта + example: DC + status: + type: string + description: Статус-результат обработки заявки + example: APPROVAL_REJECT + description: Повторный запрос SMS для подтверждения создания заявки + ResendSmsCompletionResponse: + required: + - status + type: object + properties: + payload: + $ref: '#/components/schemas/DebitCardPayload' + status: + type: string + description: Статус-результат обработки заявки + example: NEED_SMS + description: Повторный запрос SMS для подтверждения завершения оформления заявки + TooManyRequests: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: too_many_requests + error_description: + type: string + description: Сообщение об ошибке + example: "The client application has surpassed its rate limit, or number\ + \ of requests they can send in a given period of time - number of sent\ + \ SMSes isn't less than 3" + description: Превышено количество обращений в единицу времени к сервису dt-product-api + CheckDraftResponse: + required: + - formId + - requestBrokerageAccount + - requestCodeWord + type: object + properties: + formId: + type: string + description: Идентификатор заявки + example: 55A42D1698400C9EE0543863BB4C2866 + requestCodeWord: + type: boolean + description: Наличие кодового слова + example: true + requestBrokerageAccount: + type: boolean + description: Признак отображения на интерфейсе панели открытия брокерского + счёта + example: false + userStatus: + type: array + description: "Название клиентского пути. Принимает возможные значения: DT\ + \ - клиент ЦТ; NODT - действующий клиент, дополнительно может быть ука\ + зано FAMILY - клиент Семейного Банка" + items: + uniqueItems: true + type: string + enum: + - DT + - NODT + - FAMILY + description: Получен статус заявки + example: + formId: 55A42D1698400C9EE0543863BB4C2866 + requestCodeWord: true + userStatus: + - DT + - DT + requestBrokerageAccount: false + DeliveryTypesResponse: + required: + - courier + - offices + - onlyCourierDelivery + type: object + properties: + onlyCourierDelivery: + type: boolean + description: Признак доступности только курьерской доставки + example: true + courier: + $ref: '#/components/schemas/Courier' + offices: + $ref: '#/components/schemas/Offices' + description: Получен способы доставки по заданным географическим параметрам + example: + courier: + latitude: 55.659348 + cityId: 21 + cardAttributes: + namedCardEnabled: false + unnamedCardEnabled: true + longitude: 37.472996 + offices: + address: "пр-кт Вернадского, д.119" + distance: 2121 + city: + fiasId: 0c5b2444-70a0-4932-980c-b4dc0d3f02b5 + kladrId: "\t7700000000000" + name: Москва + clientAvailability: OPENED + pid: "0610" + title: ДО «ЮГО-ЗАПАДНАЯ» + prodType: "'pointone', 'pointtwo', 'serviceoffice'" + uuid: 83e92bd6-60cd-4924-91a0-571a635c3244 + constraints: + - date: с 10.02.2023 по 12.02.2023 + times: "пн-ср: 10:00-18:00" + - date: с 10.02.2023 по 12.02.2023 + times: "пн-ср: 10:00-18:00" + schedule: "'пн-пт: 10:00-20:00', 'сб: 10:00-18:00','вс: выходной'" + temporarySchedule: + - date: с 10.02.2023 по 12.02.2023 + times: + - times + - times + - date: с 10.02.2023 по 12.02.2023 + times: + - times + - times + embossingEnabled: true + metro: + - distance: 604 + lineId: 1 + lineName: Сокольническая + lineColor: E42313 + id: "1.162" + title: Юго-Западная + - distance: 604 + lineId: 1 + lineName: Сокольническая + lineColor: E42313 + id: "1.162" + title: Юго-Западная + mnemonic: MOES + addressOfficial: "197022, г. Санкт-Петербург, Каменноостровский пр-кт, д\ + . 42 Б, лит. А" + cardAttributes: + namedCardEnabled: false + unnamedCardEnabled: true + anyOfficeUnnamedEnabled: false + onlyCourierDelivery: true + Courier: + required: + - cardAttributes + - cityId + - latitude + - longitude + type: object + properties: + cardAttributes: + $ref: '#/components/schemas/CardAttributes' + cityId: + type: integer + description: Код города доставки + example: 21 + latitude: + type: number + description: Широта + example: 55.659348 + longitude: + type: number + description: Долгота + example: 37.472996 + description: Параметры курьерской доставки + example: + latitude: 55.659348 + cityId: 21 + cardAttributes: + namedCardEnabled: false + unnamedCardEnabled: true + longitude: 37.472996 + CardAttributes: + required: + - namedCardEnabled + - unnamedCardEnabled + type: object + properties: + unnamedCardEnabled: + type: boolean + description: Признак доступности неименной карты + example: true + namedCardEnabled: + type: boolean + description: Признак доступности именной карты + example: false + description: Атрибуты карты и ее доступности + example: + namedCardEnabled: false + unnamedCardEnabled: true + Offices: + required: + - address + - cardAttributes + - city + - clientAvailability + - distance + - embossingEnabled + - mnemonic + - pid + - prodType + - schedule + - title + - uuid + type: object + properties: + pid: + type: string + description: Внутрибанковский цифровой код (идентификатор) офиса + example: "0610" + uuid: + type: string + description: Идентификатор доставки в офис + example: 83e92bd6-60cd-4924-91a0-571a635c3244 + mnemonic: + type: string + description: Мнемоника офиса + example: MOES + title: + type: string + description: Наименование офиса + example: ДО «ЮГО-ЗАПАДНАЯ» + address: + type: string + description: Адрес офиса + example: "пр-кт Вернадского, д.119" + addressOfficial: + type: string + description: Юридический адрес офиса + example: "197022, г. Санкт-Петербург, Каменноостровский пр-кт, д. 42 Б,\ + \ лит. А" + cardAttributes: + $ref: '#/components/schemas/Offices_cardAttributes' + metro: + type: array + items: + $ref: '#/components/schemas/Metro' + clientAvailability: + type: string + description: Признак доступности офиса + enum: + - OPENED + - CLOSED + - CONSULT + - PERMANENTLY_LOCKED + - TEMPORARILY_LOCKED + embossingEnabled: + type: boolean + description: Признак возможности эмбоссирования карты + example: true + prodType: + type: array + description: Список характеристик (сервисов) офиса + example: "'pointone', 'pointtwo', 'serviceoffice'" + items: + type: string + enum: + - pointone + - pointtwo + - serviceoffice + - clientoffice + - cashmas + - safe + - disabled + - cashgbp + - cashchf + - momentcard + - wifi + - partner + - overdraft + - cashop + - officembip + - pilot + - dc + - cc + - pil + - mortgage + - investment + - share + - courier + - bio + schedule: + type: array + description: Расписание работы офиса (дни недели и время) + example: "'пн-пт: 10:00-20:00', 'сб: 10:00-18:00','вс: выходной'" + items: + type: string + temporarySchedule: + type: array + description: Временное расписание работы офиса + items: + $ref: '#/components/schemas/TemporarySchedule' + constraints: + type: array + description: Ограничения в работе отделения + items: + $ref: '#/components/schemas/OfficeConstraint' + distance: + type: number + description: "Расстояние от адреса клиента до офиса, м." + example: 2121 + city: + $ref: '#/components/schemas/City' + description: Список офисов доступных в указанном радиусе для получения карты + example: + address: "пр-кт Вернадского, д.119" + distance: 2121 + city: + fiasId: 0c5b2444-70a0-4932-980c-b4dc0d3f02b5 + kladrId: "\t7700000000000" + name: Москва + clientAvailability: OPENED + pid: "0610" + title: ДО «ЮГО-ЗАПАДНАЯ» + prodType: "'pointone', 'pointtwo', 'serviceoffice'" + uuid: 83e92bd6-60cd-4924-91a0-571a635c3244 + constraints: + - date: с 10.02.2023 по 12.02.2023 + times: "пн-ср: 10:00-18:00" + - date: с 10.02.2023 по 12.02.2023 + times: "пн-ср: 10:00-18:00" + schedule: "'пн-пт: 10:00-20:00', 'сб: 10:00-18:00','вс: выходной'" + temporarySchedule: + - date: с 10.02.2023 по 12.02.2023 + times: + - times + - times + - date: с 10.02.2023 по 12.02.2023 + times: + - times + - times + embossingEnabled: true + metro: + - distance: 604 + lineId: 1 + lineName: Сокольническая + lineColor: E42313 + id: "1.162" + title: Юго-Западная + - distance: 604 + lineId: 1 + lineName: Сокольническая + lineColor: E42313 + id: "1.162" + title: Юго-Западная + mnemonic: MOES + addressOfficial: "197022, г. Санкт-Петербург, Каменноостровский пр-кт, д.\ + \ 42 Б, лит. А" + cardAttributes: + namedCardEnabled: false + unnamedCardEnabled: true + anyOfficeUnnamedEnabled: false + Metro: + required: + - distance + - id + - lineColor + - lineId + - lineName + - title + type: object + properties: + id: + type: string + description: Идентификатор станции метро + example: "1.162" + title: + type: string + description: Наименование станции метро + example: Юго-Западная + distance: + type: integer + description: "Расстояние до офиса, м." + example: 604 + lineId: + type: integer + description: Идентификатор линии метро + example: 1 + lineColor: + type: string + description: Цвет линии метро + example: E42313 + lineName: + type: string + description: Наименование линии метро + example: Сокольническая + description: Список ближайших к офису станций метро + example: + distance: 604 + lineId: 1 + lineName: Сокольническая + lineColor: E42313 + id: "1.162" + title: Юго-Западная + TemporarySchedule: + type: object + properties: + date: + type: string + description: Даты работы в рамках временного расписания + example: с 10.02.2023 по 12.02.2023 + times: + type: array + description: Время работы в рамках временного расписания + items: + type: string + description: Временное расписание работы офиса + example: + date: с 10.02.2023 по 12.02.2023 + times: + - times + - times + OfficeConstraint: + type: object + properties: + date: + type: string + description: Даты работы + example: с 10.02.2023 по 12.02.2023 + times: + type: string + description: Время работы + example: "пн-ср: 10:00-18:00" + description: Ограничения в работе отделения + example: + date: с 10.02.2023 по 12.02.2023 + times: "пн-ср: 10:00-18:00" + City: + required: + - fiasId + - kladrId + - name + type: object + properties: + name: + type: string + description: Наименование города отделения + example: Москва + fiasId: + type: string + description: Код ФИАС (Федеральная информационная адресная система) города + отделения + example: 0c5b2444-70a0-4932-980c-b4dc0d3f02b5 + kladrId: + type: string + description: Код КЛАДР города отделения + example: "\t7700000000000" + description: Город расположения офиса + example: + fiasId: 0c5b2444-70a0-4932-980c-b4dc0d3f02b5 + kladrId: "\t7700000000000" + name: Москва + TimeSlotsResponse: + required: + - availableDates + - uuid + type: object + properties: + uuid: + type: string + description: Идентификатор заявки + example: 07a91616-53e1-4ee1-8045-0544e4590a18 + availableDates: + type: array + description: Список дат с доступными тайм-слотами + items: + $ref: '#/components/schemas/AvailableDates' + description: Полученные тайм-слоты для доставки карты + example: + availableDates: + - date: 2023-08-03T00:00:00.000+00:00 + slots: + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + - date: 2023-08-03T00:00:00.000+00:00 + slots: + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + uuid: 07a91616-53e1-4ee1-8045-0544e4590a18 + AvailableDates: + type: object + properties: + date: + type: string + description: Дата доступных тайм-слотов + format: date + example: 2023-08-03 + slots: + type: array + description: Список слотов + items: + $ref: '#/components/schemas/Slots' + description: Список дат с доступными тайм-слотами + example: + date: 2023-08-03T00:00:00.000+00:00 + slots: + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + - isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + Slots: + type: object + properties: + isAvailable: + type: boolean + description: Признак доступности слота + example: true + slotFrom: + type: string + description: Время начала слота + example: 10:00 + slotTo: + type: string + description: Время завершения слота + example: 11:00 + express: + type: boolean + description: Признак экспресс-доставки + example: false + description: Список слотов + example: + isAvailable: true + slotTo: 11:00 + express: false + slotFrom: 10:00 + BookTimeSlotRequest: + required: + - deliveryDate + - express + - slotFrom + - slotTo + - uuid + type: object + properties: + deliveryDate: + type: string + description: Дата тайм-слота + format: date + example: 2023-08-03 + express: + type: boolean + description: Признак экспресс-доставки + example: false + slotFrom: + type: string + description: Время начала слота + example: 10:00 + slotTo: + type: string + description: Время окончания слота + example: 11:00 + uuid: + type: string + description: Идентификатор доставки + example: 07a91616-53e1-4ee1-8045-0544e4590a18 + description: Список слотов + example: + express: false + slotTo: 11:00 + deliveryDate: 2023-08-03T00:00:00.000+00:00 + uuid: 07a91616-53e1-4ee1-8045-0544e4590a18 + slotFrom: 10:00 + FormConfirmationRequest: + required: + - isUnnamedCard + type: object + properties: + codeWord: + type: string + description: Кодовое слово + example: Код1 + isUnnamedCard: + type: boolean + description: Признак заказа неименной карты + example: true + deliveryUuid: + type: string + description: Идентификатор доставки + example: 304ad059-ae73-459c-9195-acf353589657 + courierDelivery: + $ref: '#/components/schemas/CourierDelivery' + officeDelivery: + $ref: '#/components/schemas/OfficeDelivery' + currency: + type: string + description: Код валюты + example: RUR + description: Тайм-слот забронирован для доставки карты + example: + codeWord: Код1 + isUnnamedCard: true + courierDelivery: + date: 2023-08-12T00:00:00.000+00:00 + address: "г. Москва, ул. Анохина, д. 9" + comment: Возможно не работает домофон + slotTo: 11:00 + express: true + brokerageAccountRequired: true + slotFrom: 10:00 + deliveryUuid: 304ad059-ae73-459c-9195-acf353589657 + officeDelivery: + obtainingOffice: "392" + currency: RUR + CourierDelivery: + required: + - address + - date + - express + - slotFrom + - slotTo + type: object + properties: + address: + type: string + description: Адрес доставки + example: "г. Москва, ул. Анохина, д. 9" + comment: + type: string + description: Комментарий для сотрудника + example: Возможно не работает домофон + date: + type: string + description: Дата доставки + format: date + example: 2023-08-12 + slotFrom: + type: string + description: Время начала слота доставки + example: 10:00 + slotTo: + type: string + description: Время окончания слота доставки + example: 11:00 + express: + type: boolean + description: Признак экспресс-доставки + example: true + brokerageAccountRequired: + type: boolean + description: Признак необходимости открытия брокерского счета (для передачи + в Логистику) + example: true + description: Детали курьерской доставки + example: + date: 2023-08-12T00:00:00.000+00:00 + address: "г. Москва, ул. Анохина, д. 9" + comment: Возможно не работает домофон + slotTo: 11:00 + express: true + brokerageAccountRequired: true + slotFrom: 10:00 + OfficeDelivery: + required: + - obtainingOffice + type: object + properties: + obtainingOffice: + type: string + description: Внутрибанковский цифровой код офиса + example: "392" + description: Детали доставки в офис банка + example: + obtainingOffice: "392" + FormConfirmationResponse: + required: + - status + type: object + properties: + status: + type: string + description: Статус-результат обработки заявки + example: SUCСESS + description: Детали доставки в офис банка + example: + status: SUCСESS + GetAccountsResponse: + type: object + properties: + Data: + $ref: '#/components/schemas/GetAccountsResponse_Data' + example: + Data: + Account: + - accountId: accountId + Owner: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Servicer: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + accountDescription: accountDescription + accountType: null + currency: currency + status: null + AccountDetails: + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - accountId: accountId + Owner: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Servicer: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + accountDescription: accountDescription + accountType: null + currency: currency + status: null + AccountDetails: + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - identification: identification + name: name + schemeName: RU.CBR.BBAN + Account_3: + required: + - accountDescription + - accountId + - accountType + - currency + - status + type: object + properties: + accountId: + type: string + status: + $ref: '#/components/schemas/AccountStatus_2' + currency: + type: string + accountType: + $ref: '#/components/schemas/AccountType_1' + accountDescription: + type: string + AccountDetails: + type: array + items: + $ref: '#/components/schemas/AccountDetailsEntry' + Owner: + $ref: '#/components/schemas/Owner' + Servicer: + $ref: '#/components/schemas/BranchAndFinancialInstitutionInformation_1' + example: + accountId: accountId + Owner: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Servicer: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + accountDescription: accountDescription + accountType: null + currency: currency + status: null + AccountDetails: + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - identification: identification + name: name + schemeName: RU.CBR.BBAN + AccountStatus_2: + type: string + enum: + - Enabled + - Disabled + AccountType_1: + type: string + enum: + - Business + - Personal + AccountDetailsEntry: + required: + - identification + - schemeName + type: object + properties: + name: + type: string + schemeName: + type: string + enum: + - RU.CBR.BBAN + - RU.CBR.EPID + - RU.CBR.PAN + - RU.CBR.MTEL + - RU.CBR.ORID + identification: + type: string + example: + identification: identification + name: name + schemeName: RU.CBR.BBAN + Owner: + required: + - identification + - name + type: object + properties: + name: + type: string + mobileNumber: + type: string + countryOfResidence: + type: string + cityOfBirth: + type: string + birthDate: + type: string + format: DateTime + identification: + $ref: '#/components/schemas/Identification' + postalAddress: + $ref: '#/components/schemas/PostalAddress_1' + example: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Identification: + required: + - identification + - schemeName + type: object + properties: + schemeName: + type: string + enum: + - RU.CBR.TXID + - RU.CBR.LEI + - RU.CBR.PASP + - RU.CBR.CLID + - RU.CBR.QRST + - RU.CBR.TAXT + - RU.CBR.OGRN + - RU.CBR.SNILS + - RU.CBR.PAN + - RU.CBR.MTEL + - RU.CBR.BBAN + identification: + type: string + example: + identification: identification + schemeName: RU.CBR.TXID + PostalAddress_1: + type: object + properties: + addressType: + $ref: '#/components/schemas/AddressType' + addressLine: + type: array + items: + type: string + streetName: + type: string + buildingNumber: + type: string + postCode: + type: string + townName: + type: string + countrySubDivision: + type: string + country: + type: string + example: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + AddressType: + type: string + enum: + - Business + - Correspondence + - DeliveryTo + - MailTo + - POBox + - Postal + - Residential + - Statement + BranchAndFinancialInstitutionInformation_1: + required: + - BankIdentification + - name + type: object + properties: + name: + type: string + BankIdentification: + type: array + items: + $ref: '#/components/schemas/BankIdentification' + OrganizationIdentification: + type: array + items: + $ref: '#/components/schemas/OrganizationIdentification' + CorrespondentAccount: + $ref: '#/components/schemas/CorrespondentAccount' + PostalAddress: + $ref: '#/components/schemas/PostalAddress_1' + example: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + BankIdentification: + required: + - identification + - schemeName + type: object + properties: + schemeName: + type: string + enum: + - RU.CBR.BICFI + - RU.CBR.BIC + identification: + type: string + example: + identification: identification + schemeName: RU.CBR.BICFI + OrganizationIdentification: + required: + - identification + - schemeName + type: object + properties: + schemeName: + type: string + enum: + - RU.CBR.TXID + - RU.CBR.LEI + - RU.CBR.TAXT + - RU.CBR.OGRN + - RU.CBR.OKPO + identification: + type: string + example: + identification: identification + schemeName: RU.CBR.TXID + CorrespondentAccount: + required: + - identification + - schemeName + type: object + properties: + schemeName: + type: string + enum: + - RU.CBR.BBAN + - RU.CBR.EPID + - RU.CBR.PAN + - RU.CBR.MTEL + - RU.CBR.ORID + identification: + type: string + example: + identification: identification + schemeName: RU.CBR.BBAN + OBRUErrorResponse_1: + required: + - Errors + - code + - message + type: object + properties: + code: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Высокоуровневый текстовый код ошибки, необходимый для клас\ + сификации" + example: "400" + message: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: "Краткое сообщение об ошибке. Например, «что-то не так с пр\ + едоставленными параметрами запроса»" + example: Bad Request + Errors: + maxItems: 50 + minItems: 1 + type: array + items: + $ref: '#/components/schemas/OBRUError_1' + additionalProperties: false + description: Контейнер с детализацией ошибки + OBRUError_1: + required: + - errorCode + - message + type: object + properties: + errorCode: + $ref: '#/components/schemas/OBRUErrorResponseErrorCode' + message: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: Описание ошибки + example: Обязательное поле не указано + path: + maxLength: 500 + minLength: 1 + pattern: "^[\\w\\W]{1,500}$" + type: string + description: "Путь к элементу с ошибкой в JSON объекте. Рекомендуемое, н\ + о не обязательное поле" + example: Data.Model.Object.name + url: + type: string + description: "URL для помощи в устранении проблемы, Также через URL можн\ + о предоставлять дополнительную информацию" + format: uri + example: https://example.com/error-description + additionalProperties: false + description: Контейнер с ошибкой + BalanceResponse_1: + maxProperties: 3 + minProperties: 3 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/BalanceResponse_1_Data' + Links: + $ref: '#/components/schemas/AccountResponse_Links' + Meta: + $ref: '#/components/schemas/BalanceResponse_1_Meta' + additionalProperties: false + description: Ответ на запрос об остатке на счете + example: + Meta: null + Links: + self: https://sb.example.ru/v1.3/example + Data: null + DataBalanceResponse: + type: object + properties: + Balance: + maxItems: 50 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/Balance' + additionalProperties: false + description: Полезная нагрузка ответа на запрос об остатке на счете + Balance: + required: + - Amount + - accountId + - creditDebitIndicator + - dateTime + - type + type: object + properties: + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса счета" + example: this-is-a-slug-format-account-id + type: + description: Тип остатка + allOf: + - $ref: '#/components/schemas/BalanceType_1' + Amount: + $ref: '#/components/schemas/Balance_Amount' + creditDebitIndicator: + description: Определяет является остаток кредитовым или дебетовым + allOf: + - $ref: '#/components/schemas/CreditDebitCode' + dateTime: + description: "Дата, на которую рассчитан остаток" + allOf: + - $ref: '#/components/schemas/ISODateTime' + CreditLine: + maxItems: 50 + minItems: 0 + type: array + description: Кредитная линия + items: + $ref: '#/components/schemas/OBRUCreditLine' + additionalProperties: false + description: Остаток на счете + x-openapiru-object-type-contract: true + BalanceType_1: + type: string + description: Тип остатка + enum: + - ClosingAvailable + - ClosingBooked + - ClosingCleared + - Expected + - OpeningAvailable + - OpeningBooked + - OpeningCleared + - PreviouslyClosedBooked + ActiveOrHistoricCurrencyAndAmount_1: + required: + - amount + - currency + type: object + properties: + amount: + description: Сумма денежных средств + allOf: + - $ref: '#/components/schemas/ActiveCurrencyAndAmountSimpleType' + currency: + description: "Код валюты, соответствующий международному стандарту ISO 4217" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + additionalProperties: false + description: Сумма денежных средств и код валюты + OBRUCreditLine: + required: + - Amount + - included + type: object + properties: + included: + type: boolean + description: Показывает включена или нет кредитная линия в расчет остатка + example: false + Amount: + $ref: '#/components/schemas/OBRUCreditLine_Amount' + additionalProperties: false + description: "Набор элементов, используемых для предоставления подробной инф\ + ормации о кредитной линии" + TransactionResponse: + maxProperties: 3 + minProperties: 3 + required: + - Data + type: object + properties: + Data: + $ref: '#/components/schemas/TransactionResponse_Data' + Links: + $ref: '#/components/schemas/StatementResponse_Links' + Meta: + $ref: '#/components/schemas/BalanceResponse_1_Meta' + additionalProperties: false + description: Ответ на запрос информации об операциях по счету + example: + Meta: null + Links: null + Data: null + DataTransactionResponse: + type: object + properties: + Transaction: + maxItems: 50 + minItems: 0 + type: array + description: Список операций по счету + items: + $ref: '#/components/schemas/TransactionHistory' + additionalProperties: false + description: Полезная нагрузка ответа на запрос об операциях по счету + TransactionHistory: + required: + - BankTransactionCode + - accountId + - bookingDateTime + - creditDebitIndicator + - status + - transactionId + type: object + properties: + transactionId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации рессурса операции по счету" + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса accounts" + groupId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный идентификатор, используемый для идентификации г\ + руппы связанных операций по счету" + transactionInformation: + pattern: "^[\\w\\W]{1,240}$" + type: string + description: Сообщение отправителя получателю денежных средств + example: Сообщение отправителя получателю денежных средств + Amount: + $ref: '#/components/schemas/TransactionHistory_Amount' + creditDebitIndicator: + description: Определяет является ли операция дебетовая или кредитовая + example: Debit + allOf: + - $ref: '#/components/schemas/CreditDebitCode' + status: + description: Статус операции по счету + example: AcceptedSettlementCompleted + allOf: + - $ref: '#/components/schemas/TransactionStatusCode' + BankTransactionCode: + $ref: '#/components/schemas/TransactionHistory_BankTransactionCode' + bookingDateTime: + description: "Дата и время, когда запись об операции по счету публикуетс\ + я на счете в бухгалтерской книге обслуживающей организации. Использует\ + ся стандарт ISO8601" + allOf: + - $ref: '#/components/schemas/ISODateTime' + valueDateTime: + description: "Дата и время, когда активы становятся доступными владельцу\ + \ счета в случае ввода кредита или перестают быть доступными владельцу\ + \ счета в случае ввода дебетовой операции по счету" + allOf: + - $ref: '#/components/schemas/ISODateTime' + ChargeAmount: + $ref: '#/components/schemas/TransactionHistory_ChargeAmount' + InstructedAmount: + $ref: '#/components/schemas/TransactionHistory_InstructedAmount' + Debtor: + $ref: '#/components/schemas/TransactionHistory_Debtor' + DebtorAgent: + $ref: '#/components/schemas/ReportEntry_DebtorAgent' + DebtorAccount: + $ref: '#/components/schemas/TransactionHistory_DebtorAccount' + CreditorAgent: + $ref: '#/components/schemas/ReportEntry_CreditorAgent' + CreditorAccount: + $ref: '#/components/schemas/TransactionHistory_CreditorAccount' + Creditor: + $ref: '#/components/schemas/TransactionHistory_Creditor' + CardTransaction: + $ref: '#/components/schemas/TransactionHistory_CardTransaction' + RemittanceInformation: + $ref: '#/components/schemas/TransactionHistory_RemittanceInformation' + additionalProperties: false + description: Операция по счету + ActiveOrHistoricCurrencyAndAmount_2: + required: + - amount + - currency + type: object + properties: + amount: + description: Сумма денежных средств + allOf: + - $ref: '#/components/schemas/ActiveCurrencyAndAmountSimpleType' + currency: + description: "Код валюты, соответствующий международному стандарту ISO 4217" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyCode' + additionalProperties: false + description: Сумма денежных средств и код валюты + CardTransaction: + type: object + properties: + Card: + $ref: '#/components/schemas/PaymentCard' + Transaction: + $ref: '#/components/schemas/CardTransaction_Transaction' + additionalProperties: false + description: "Предоставляет данные по карте (номер, платежная система), терм\ + иналу (номер, идентификатор) и транзакционные данные, используемые для уни\ + кальной идентификации операции по карте" + PaymentCard: + type: object + properties: + cardScheme: + $ref: '#/components/schemas/CardSchemeNameCode' + additionalCardData: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: "Дополнительные сведения, специфичные для эмитента карты" + example: Дополнительные сведения + PaymentCardData: + $ref: '#/components/schemas/PlainCardData' + additionalProperties: false + description: Данные по платежной карте + CardIndividualTransaction: + type: object + properties: + authorizationCode: + maxLength: 35 + minLength: 3 + pattern: "^[\\w\\W]{3,35}$" + type: string + description: Код авторизации операции + example: "1234" + additionalProperties: false + description: "Сведения об отдельной операции по карте, записанные на POI-тер\ + минале (точке взаимодействия)" + AccountPaymentCardsResponse: + type: object + properties: + Data: + $ref: '#/components/schemas/AccountPaymentCardsResponse_Data' + Links: + $ref: '#/components/schemas/Links_1' + Meta: + $ref: '#/components/schemas/Meta_1' + additionalProperties: false + description: Список платежных карт и их идентификаторы + example: + Meta: + totalPages: 1 + Links: + next: https://sb.example.ru/v1.3/example?page=1 + last: https://sb.example.ru/v1.3/example?page=1 + prev: https://sb.example.ru/v1.3/example?page=1 + self: https://sb.example.ru/v1.3/example?page=1 + first: https://sb.example.ru/v1.3/example?page=1 + Data: + PaymentCard: + - null + - null + - null + - null + - null + AccountPaymentCardsData: + required: + - PaymentCardData + - accountId + - cardScheme + - paymentCardId + - paymentCardName + - paymentCardType + type: object + properties: + accountId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса Счета" + example: this-is-a-slug-format-account-id + paymentCardId: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации платежной карты" + example: this-is-a-slug-format-payment-card-id + paymentCardType: + type: string + description: Тип платежной карты + example: debit + enum: + - debit + - credit + paymentCardName: + maxLength: 64 + minLength: 1 + pattern: "^[\\w\\W]{1,64}$" + type: string + description: "Наименование, ассоциированное с платежной картой конечного\ + \ Пользователя" + example: Экономная карта + PaymentCardData: + $ref: '#/components/schemas/PlainCardData2' + cardScheme: + $ref: '#/components/schemas/CardSchemeNameCode' + iconUrl: + maxLength: 2048 + minLength: 1 + pattern: "^[\\w\\W]{1,2048}$" + type: string + description: URL-адрес для получения информации в виде значка (icon) + example: https://mybank.ru/products/debit-card/mybrend.ico + designUrl: + maxLength: 2048 + minLength: 1 + pattern: "^[\\w\\W]{1,2048}$" + type: string + description: URL-адрес для получения информации в виде изображения + example: https://mybank.ru/products/debit-card/mybrend.png + description: "Информация о платежной карте, связанной со сетом клиента" + PlainCardData2: + required: + - PAN + - cardStatus + - expiryDate + type: object + properties: + PAN: + pattern: "^[0-9]{4}$" + type: string + description: "Маскированный учетный номер карты (PAN) или номер карты, о\ + граниченный последними 4 цифрами." + example: "0001" + effectiveDate: + description: "Дата, начиная с которой карту можно использовать" + example: 12/2021 + allOf: + - $ref: '#/components/schemas/ISOYearMonth' + expiryDate: + description: Дата окончания срока действия карты + example: 12/2025 + allOf: + - $ref: '#/components/schemas/ISOYearMonth' + cardStatus: + type: string + description: |- + Статус доступности карты: + - pending - Карта выпущена но еще не активирована Пользователем + - active - Доступны все активные операции + - blocked - Все операции по карте заблокированы + example: active + enum: + - pending + - active + - blocked + additionalProperties: false + description: "Конфиденциальные данные платежной карты, ассоциированной со сч\ + етом" + CardSchemeNameCode: + type: string + description: Наименование платежной системы или схемы карты + example: MIR + enum: + - MIR + - AmericanExpress + - Diners + - Discover + - MasterCard + - VISA + - ArCa + - BELKART + - ELCART + - JCB + - UnionPay + x-enum-descriptions: + - Российская национальная платежная система + - Международная платежная система AmericanExpress + - Международная платежная система Diners + - Международная платежная система Discover + - Международная платежная система MasterCard + - Международная платежная система VISA + - Армянская национальная платежная система ArCa + - Белорусская национальная платежная система BELKART + - Киргизская национальная платежная система ELCART + - Платежная система Японии JCB + - Национальная платежная система Китая UnionPay + x-enum-varnames: + - MIR + - AmericanExpress + - Diners + - Discover + - MasterCard + - VISA + - ArCa + - BELKART + - ELCART + - JCB + - UnionPay + ReportRequest: + required: + - date + - type + type: object + properties: + type: + type: string + description: | + Код типа отчета: + * `1` - Агрегированный отчет; + * `2` - Детализированный отчет + example: "2" + enum: + - "1" + - "2" + date: + type: string + description: "Дата, на которую необходимо сформировать отчет" + format: date + example: 2022-07-30 + shops: + type: array + description: "Коды магазинов, по которым нужна детализированная информац\ + ия" + example: + - F76E + - F82A + - F11C + - F52B + items: + type: string + example: + date: 2022-07-30T00:00:00.000+00:00 + shops: + - F76E + - F82A + - F11C + - F52B + type: "2" + ReportResponse: + type: object + properties: + reqId: + type: string + description: Идентификатор запроса на создание отчета + format: uuid + example: 34eb7e7e-66db-42fa-9b81-544fed77c871 + example: + reqId: 34eb7e7e-66db-42fa-9b81-544fed77c871 + RegTerminalRequest: + required: + - accountNumber + - legalId + - merchantId + type: object + properties: + legalId: + pattern: ".{12}" + type: string + description: Регистрационный номер ЮЛ в СБП + example: LA0000004756 + merchantId: + pattern: ".{12}" + type: string + description: Регистрационный номер магазина в СБП + example: MA0000002752 + accountNumber: + pattern: "^\\d{20}" + type: string + description: Номер счета в Банке-участнике СБП + example: "40702810102300000001" + status: + type: string + description: | + Статус терминала: + * `Open` - открыт, доступен для выполнения операций; + * `Close` - закрыт, выполнение операций невозможно; + * `Block` - заблокирован, выполнение операций невозможно. + example: Open + enum: + - Open + - Close + - Block + example: + merchantId: MA0000002752 + legalId: LA0000004756 + accountNumber: "40702810102300000001" + status: Open + RegTerminalResponse: + required: + - status + type: object + properties: + termNo: + pattern: "^\\d{10}" + type: string + description: Идентификатор терминала + example: "9008056701" + status: + type: string + description: | + Статус обработки запроса: + * `Rejected` - отказ в обработке; + * `Postponed` - отложен; + * `Accepted` - принят к обработке; + * `Executed` - исполнен. + example: Executed + enum: + - Rejected + - Postponed + - Accepted + - Executed + example: + termNo: "9008056701" + status: Executed + MerchantInfoResponse: + type: object + properties: + merchantId: + pattern: ".{12}" + type: string + description: Регистрационный номер ТСП в СБП + example: MA0000002752 + brandName: + type: string + description: Название магазина + example: Технониколь + mcc: + type: string + description: MCC-код магазина + example: "4816" + qrType: + type: string + description: Тип QR-кода + example: static + status: + type: string + description: Код текущего статуса ТСП + example: "2" + address: + $ref: '#/components/schemas/Address_2' + terminals: + type: array + items: + $ref: '#/components/schemas/Terminal' + description: Информация о ТСП + example: + brandName: Технониколь + address: + zip: "125362" + settlementType: г. + country: RU + streetType: ул. + street: Подмосковная + region: "45" + house: "21" + settlement: Москва + merchantId: MA0000002752 + qrType: static + mcc: "4816" + terminals: + - termNo: "9008056701" + status: "1" + - termNo: "9008056701" + status: "1" + status: "2" + Address_2: + type: object + properties: + zip: + type: string + description: Индекс + example: "125362" + country: + type: string + description: Код страны + example: RU + region: + type: string + description: Код региона по ОКТМО (первые два символа) + example: "45" + settlementType: + type: string + description: Тип населенного пункта + example: г. + settlement: + type: string + description: Наименование населенного пункта + example: Москва + streetType: + type: string + description: Тип улицы + example: ул. + street: + type: string + description: Наименование улицы + example: Подмосковная + house: + type: string + description: Номер дома + example: "21" + description: Информация о фактическом адресе + example: + zip: "125362" + settlementType: г. + country: RU + streetType: ул. + street: Подмосковная + region: "45" + house: "21" + settlement: Москва + Terminal: + type: object + properties: + termNo: + pattern: "^\\d{10}" + type: string + description: Идентификатор терминала + example: "9008056701" + status: + type: string + description: | + Код текущего статуса терминала: + * `1` - Открыт; + * `2` - Закрыт; + * `3` - Заблокирован. + example: "1" + enum: + - "1" + - "2" + - "3" + description: Данные о терминале + example: + termNo: "9008056701" + status: "1" + LegalInfoResponse: + type: object + properties: + legalId: + type: string + description: Регистрационный номер ЮЛ в СБП + example: LA0000004756 + lastName: + type: string + description: Фамилия + firstName: + type: string + description: Имя + middleName: + type: string + description: Отчество + name: + type: string + description: Наименование ЮЛ + example: ООО "ТехноНИКОЛЬ-Строительные Системы" + type: + type: string + description: Организационно-правовая форма ЮЛ + example: ООО + inn: + type: string + description: ИНН ЮЛ + example: "7706812159" + kpp: + type: string + description: КПП ЮЛ (отсутствует в случае ИП) + example: "770501001" + ogrn: + type: string + description: ОГРН ЮЛ + example: "1147746831352" + contractNumber: + type: string + description: Номер договора на обслуживание + example: СБПС2В-20200911 + contractDate: + type: string + description: Дата заключения договора на обслуживание + format: date + example: 2020-09-11 + status: + type: string + description: Код текущего статуса ЮЛ + example: "2" + address: + $ref: '#/components/schemas/Address_2' + accounts: + type: array + items: + $ref: '#/components/schemas/Account_4' + merchants: + type: array + items: + $ref: '#/components/schemas/Merchant' + example: + ogrn: "1147746831352" + lastName: lastName + contractDate: 2020-09-11T00:00:00.000+00:00 + address: + zip: "125362" + settlementType: г. + country: RU + streetType: ул. + street: Подмосковная + region: "45" + house: "21" + settlement: Москва + legalId: LA0000004756 + inn: "7706812159" + contractNumber: СБПС2В-20200911 + kpp: "770501001" + type: ООО + firstName: firstName + name: ООО "ТехноНИКОЛЬ-Строительные Системы" + middleName: middleName + accounts: + - forB2C: "1" + accountNumber: "40702810102300000001" + type: LegalAct + memberId: "600000000015" + - forB2C: "1" + accountNumber: "40702810102300000001" + type: LegalAct + memberId: "600000000015" + merchants: + - merchantId: "9008056701" + status: "1" + - merchantId: "9008056701" + status: "1" + status: "2" + Account_4: + type: object + properties: + memberId: + type: string + description: Идентификатор Банка участника СБП + example: "600000000015" + accountNumber: + type: string + description: Номер счета + example: "40702810102300000001" + type: + type: string + description: Тип счета + example: LegalAct + forB2C: + type: string + description: Признак счета для отправки переводов B2C + example: "1" + description: Информация о счете ЮЛ + example: + forB2C: "1" + accountNumber: "40702810102300000001" + type: LegalAct + memberId: "600000000015" + Merchant: + type: object + properties: + merchantId: + pattern: "^\\d{10}" + type: string + description: Идентификатор ТСП + example: "9008056701" + status: + type: string + description: | + Код текущего статуса ТСП: + * `1` - Новый; + * `2` - Зарегистрирован; + * `3` - На удаление. + example: "1" + enum: + - "1" + - "2" + - "3" + description: Данные о ТСП + example: + merchantId: "9008056701" + status: "1" + OneTimePaymentUrlRequest: + required: + - amount + - client + - merchantId + - name + - payeeAccount + - paymentPurpose + - takeTax + type: object + properties: + client: + $ref: '#/components/schemas/ClientB2B' + name: + maxLength: 140 + minLength: 1 + type: string + description: Наименование платежной ссылки + example: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни платежной ссылки в минутах + example: 4320 + default: 4320 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: + maxLength: 1024 + type: string + description: Ссылка для перехода после выполнения платежа + example: https://exampletsp.io/qwertyui + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + uip: + maxLength: 35 + minLength: 1 + type: string + description: Уникальный идентификатор платежа + example: 281000670LSS7DN18SJQDNP4B05KLJL2 + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "3664069397" + example: + amount: 1000000 + redirectUrl: https://exampletsp.io/qwertyui + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + client: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + payerInn: "3664069397" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + ttl: 4320 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + takeTax: true + ClientB2B: + required: + - b2bClientId + - partnerId + type: object + properties: + b2bClientId: + type: string + description: "Идентификатор клиента, от имени которого выполняется запро\ + с" + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: + type: integer + description: Идентификатор партнера + format: int64 + example: 214 + description: Контекст клиента + example: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + TakeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + PaymentUrl: + required: + - image + - merchantId + - name + - payeeAccount + - qrcId + - qrcType + - registrationDate + - takeTax + type: object + properties: + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платёжной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: + type: string + description: Платёжная ссылка + example: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + name: + maxLength: 140 + minLength: 1 + type: string + description: Наименование платёжной ссылки + example: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + qrcType: + $ref: '#/components/schemas/QrcType' + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + image: + type: string + description: Изображение base64encoded. В формате image/png + example: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + lastPayment: + $ref: '#/components/schemas/LastPayment' + uip: + maxLength: 35 + minLength: 1 + type: string + description: Уникальный идентификатор платежа + example: 281000670LSS7DN18SJQDNP4B05KLJL2 + registrationDate: + type: string + description: Дата и время регистрации платежной ссылки в формате ISO 8601 + format: date-time + example: 2022-01-10T12:33:25Z + expirationDate: + type: string + description: Дата и время истечения срока жизни платежной ссылки в формате + ISO 8601 + format: date-time + example: 2022-01-13T12:33:25Z + description: Информация о платёжной ссылке + example: + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + lastPayment: + payerAccount: "40702810901400001130" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + timestamp: 2022-05-26T09:09:32Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: null + expirationDate: 2022-01-13T12:33:25Z + QrcType: + type: string + description: | + Тип платежной ссылки: + * `ONETIME` - Одноразовая платёжная ссылка; + * `REUSABLE` - Многоразовая платёжная ссылка + enum: + - ONETIME + - REUSABLE + LastPayment: + required: + - amount + - currency + - payerAccount + - payerInfo + - paymentPurpose + - taxAmount + - timestamp + type: object + properties: + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет списания платежа + example: "40702810901400001130" + currency: + $ref: '#/components/schemas/Currency' + timestamp: + type: string + description: Дата и время выполнения Операции СБП B2B в формате ISO 8601 + format: date-time + example: 2022-05-26T09:09:32Z + payerInfo: + $ref: '#/components/schemas/ClientInfo_2' + description: Информация о последнем входящем платеже + example: + payerAccount: "40702810901400001130" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + timestamp: 2022-05-26T09:09:32Z + Currency: + type: string + description: Код валюты платежа + enum: + - RUR + - RUB + ClientInfo_2: + required: + - bankCorrAccount + - bankName + - bik + - inn + - name + type: object + properties: + name: + maxLength: 140 + minLength: 1 + type: string + description: Наименование ЮЛ плательщика/получателя + example: OOO Ромашка + inn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика/получателя + example: "911006876365" + bik: + pattern: "^\\d{9}$" + type: string + description: БИК банка плательщика/получателя + example: "044525593" + accountType: + maxLength: 4 + minLength: 4 + type: string + description: Тип идентификатора номера счета плательщика + example: BBAN + bankName: + maxLength: 50 + minLength: 1 + type: string + description: Наименование банка плательщика/получателя + example: АО "АЛЬФА-БАНК" + bankCorrAccount: + pattern: "^\\d{20}$" + type: string + description: Корреспондентский счет банка плательщика/получателя + example: "30101810200000000593" + description: Информация о плательщике или получателе + example: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + ReusablePaymentUrlRequest: + required: + - client + - merchantId + - name + - payeeAccount + - takeTax + type: object + properties: + client: + $ref: '#/components/schemas/ClientB2B' + name: + maxLength: 140 + minLength: 1 + type: string + description: Наименование платежной ссылки + example: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: + maxLength: 1024 + type: string + description: Ссылка для перехода после выполнения платежа + example: https://exampletsp.io/qwertyui + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "3664069397" + example: + amount: 1000000 + redirectUrl: https://exampletsp.io/qwertyui + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + client: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + payerInn: "3664069397" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + takeTax: true + PostBatchPaymentUrlRequest: + required: + - client + - paymentUrls + type: object + properties: + client: + $ref: '#/components/schemas/ClientB2B' + paymentUrls: + type: array + items: + $ref: '#/components/schemas/BatchPaymentUrlRequest' + description: Данные запроса на регистрацию массива платёжных ссылок + example: + client: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + paymentUrls: + - amount: 1000000 + redirectUrl: https://exampletsp.io/qwertyui + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + payerInn: "3664069397" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + ttl: 4320 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + takeTax: true + - amount: 1000000 + redirectUrl: https://exampletsp.io/qwertyui + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + payerInn: "3664069397" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + ttl: 4320 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + takeTax: true + BatchPaymentUrlRequest: + required: + - merchantId + - name + - payeeAccount + - qrcType + - takeTax + type: object + properties: + name: + maxLength: 140 + minLength: 1 + type: string + description: "Наименование платежной ссылки, уникальное в рамках одного\ + \ массива" + example: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + qrcType: + example: ONETIME + allOf: + - $ref: '#/components/schemas/QrcType' + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни одноразовой платёжной ссылки в минутах + example: 4320 + default: 4320 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: + maxLength: 1024 + type: string + description: Ссылка для перехода после выполнения платежа + example: https://exampletsp.io/qwertyui + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + uip: + maxLength: 35 + minLength: 1 + type: string + description: Уникальный идентификатор платежа для одноразовой платёжной + ссылки + example: 281000670LSS7DN18SJQDNP4B05KLJL2 + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "3664069397" + description: "Данные платёжной ссылки, регистрируемой в массиве" + example: + amount: 1000000 + redirectUrl: https://exampletsp.io/qwertyui + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + payerInn: "3664069397" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + ttl: 4320 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + takeTax: true + PostBatchPaymentUrlResponse: + type: object + properties: + batchId: + type: string + description: Идентификатор массива платёжных ссылок + example: a7631fbb-f94f-4c17-1e13-626b4e25585c + example: + batchId: a7631fbb-f94f-4c17-1e13-626b4e25585c + GetPaymentUrlsResponse: + required: + - paymentUrls + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + paymentUrls: + type: array + items: + $ref: '#/components/schemas/PaymentUrl' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + paymentUrls: + - image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + lastPayment: + payerAccount: "40702810901400001130" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + timestamp: 2022-05-26T09:09:32Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: null + expirationDate: 2022-01-13T12:33:25Z + - image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + lastPayment: + payerAccount: "40702810901400001130" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + timestamp: 2022-05-26T09:09:32Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: null + expirationDate: 2022-01-13T12:33:25Z + UpdateStatusPaymentUrls: + required: + - client + - paymentUrls + type: object + properties: + client: + $ref: '#/components/schemas/ClientB2B' + paymentUrls: + type: array + items: + $ref: '#/components/schemas/PaymentUrlStatuses' + description: Данные запроса на обновление статусов платёжных ссылок + example: + client: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + paymentUrls: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + isActive: true + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + isActive: true + PaymentUrlStatuses: + required: + - isActive + - qrcId + type: object + properties: + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платёжной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + isActive: + type: boolean + description: Статус платёжной ссылки + example: true + example: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + isActive: true + GetBatchPaymentUrlResponse: + required: + - paymentUrls + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + status: + type: string + description: | + Статус регистрации массива платёжных ссылок. Принимает возможные значения: + * `IN_PROGRESS` - В обработке; + * `COMPLETE` - Регистрация выполнена + example: COMPLETE + enum: + - IN_PROGRESS + - COMPLETE + paymentUrls: + type: array + items: + $ref: '#/components/schemas/BatchPaymentUrlResponse' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + paymentUrls: + - image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + registrationStatus: REGISTERED + redirectUrl: https://exampletsp.io/qwertyui + errorDescription: "Возникла ошибка при регистрации QR со стороны НСПК: {Т\ + екст ошибки от НСПК}." + payerInn: "3664069397" + ttl: 4320 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + expirationDate: 2022-01-13T12:33:25Z + - image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + registrationStatus: REGISTERED + redirectUrl: https://exampletsp.io/qwertyui + errorDescription: "Возникла ошибка при регистрации QR со стороны НСПК: {Т\ + екст ошибки от НСПК}." + payerInn: "3664069397" + ttl: 4320 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + expirationDate: 2022-01-13T12:33:25Z + status: COMPLETE + BatchPaymentUrlResponse: + required: + - name + - payeeAccount + - qrcType + - registrationStatus + - takeTax + type: object + properties: + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: + type: string + description: Платежная ссылка + example: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + name: + maxLength: 140 + minLength: 1 + type: string + description: Наименование платежной ссылки + example: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни одноразовой платёжной ссылки в минутах + example: 4320 + default: 4320 + qrcType: + example: ONETIME + allOf: + - $ref: '#/components/schemas/QrcType' + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: + maxLength: 1024 + type: string + description: Ссылка для перехода после выполнения платежа + example: https://exampletsp.io/qwertyui + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + image: + type: string + description: Изображение base64encoded. В формате image/png + example: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + uip: + maxLength: 35 + minLength: 1 + type: string + description: Уникальный идентификатор платежа + example: 281000670LSS7DN18SJQDNP4B05KLJL2 + payerInn: + pattern: "^((\\d{10})|(\\d{12}))$" + type: string + description: ИНН плательщика + example: "3664069397" + registrationDate: + type: string + description: Дата и время регистрации платежной ссылки в формате ISO 8601 + format: date-time + example: 2022-01-10T12:33:25Z + expirationDate: + type: string + description: Дата и время истечения срока жизни платежной ссылки в формате + ISO 8601 + format: date-time + example: 2022-01-13T12:33:25Z + registrationStatus: + type: string + description: | + Статус регистрации платёжной ссылки. Принимает возможные значения: + * `REGISTERED` - Платёжная ссылка зарегистрирована; + * `ERROR` - Ошибка при регистрации платёжной ссылки + example: REGISTERED + enum: + - REGISTERED + - ERROR + errorDescription: + type: string + description: Описание ошибки при регистрации платёжной ссылки + example: "Возникла ошибка при регистрации QR со стороны НСПК: {Текст оши\ + бки от НСПК}." + description: Информация о платежной ссылке + example: + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + amount: 1000000 + registrationStatus: REGISTERED + redirectUrl: https://exampletsp.io/qwertyui + errorDescription: "Возникла ошибка при регистрации QR со стороны НСПК: {Те\ + кст ошибки от НСПК}." + payerInn: "3664069397" + ttl: 4320 + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + merchantId: MF0000000001 + name: Ссылка для оплаты ИП Иванов И.П. + registrationDate: 2022-01-10T12:33:25Z + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: ONETIME + expirationDate: 2022-01-13T12:33:25Z + PaymentUrlData: + required: + - address + - brandName + - legalId + - legalName + - mcc + - memberId + - merchantId + - qrcId + - qrcType + - takeTax + type: object + properties: + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + qrcType: + $ref: '#/components/schemas/QrcType' + legalId: + pattern: "^.{12}$" + type: string + description: Регистрационный номер ЮЛ или ИП (Получателя) + example: LF0000000001 + legalName: + maxLength: 512 + type: string + description: Сокращенное наименование ЮЛ или ИП + example: ООО "Кофейня у Артёма" + memberId: + pattern: "^.{12}$" + type: string + description: Идентификатор Банка Получателя + example: "100000000001" + brandName: + maxLength: 35 + type: string + description: Торговое наименование ТСП + example: Кофейня у Артёма + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Номер счета получателя платежа + example: "40702810100010000001" + merchantId: + pattern: "^.{12}$" + type: string + description: Идентификатор ТСП + example: MF0000000001 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + address: + maxLength: 140 + minLength: 1 + type: string + description: Фактический адрес ТСП + example: "г. Воронеж, ул. Лисюкова, д.5, стр.1" + mcc: + pattern: "^\\d{4}$" + type: string + description: MCC-код + example: "4122" + fraudScore: + maxLength: 16 + minLength: 16 + type: string + description: Идентификатор подозрительной операции Агента ТСП + example: "0000000000000000" + inn: + type: string + description: ИНН Получателя (ЮЛ или ИП) + example: "4285733785" + redirectUrl: + maxLength: 1024 + type: string + description: Ссылка для перехода после выполнения платежа + example: https://exampletsp.io/qwertyui + agentId: + pattern: "^.{12}$" + type: string + description: "Идентификатор Агента ТСП, который зарегистрировал платежну\ + ю ссылку СБП (Банк Получателя)" + example: A00000000001 + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + uip: + maxLength: 35 + minLength: 1 + type: string + description: Уникальный идентификатор платежа + example: 281000670LSS7DN18SJQDNP4B05KLJL2 + description: Данные платёжной ссылки СБП + example: + brandName: Кофейня у Артёма + amount: 1000000 + fraudScore: "0000000000000000" + agentId: A00000000001 + address: "г. Воронеж, ул. Лисюкова, д.5, стр.1" + redirectUrl: https://exampletsp.io/qwertyui + legalId: LF0000000001 + inn: "4285733785" + mcc: "4122" + takeTax: true + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + legalName: ООО "Кофейня у Артёма" + merchantId: MF0000000001 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810100010000001" + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + qrcType: null + memberId: "100000000001" + GetIncomingPaymentsResponse: + required: + - payments + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + payments: + type: array + items: + $ref: '#/components/schemas/IncomingPayment' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + payments: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001289" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + payeeAccount: "40702810901400001130" + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + timestamp: 2022-05-26T09:09:32Z + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001289" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + payeeAccount: "40702810901400001130" + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + timestamp: 2022-05-26T09:09:32Z + IncomingPayment: + required: + - amount + - payerInfo + - paymentPurpose + - qrcId + - recipientInfo + - timestamp + type: object + properties: + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + nspkTransactionId: + maxLength: 32 + type: string + description: Идентификатор операции НСПК + example: B467FC50C59A469A9898AB7B05EE3F07 + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: + pattern: "^\\d{20}$" + type: string + description: Счет зачисления платежа + example: "40702810901400001130" + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет списания + example: "40702810901400001289" + currency: + $ref: '#/components/schemas/Currency' + timestamp: + type: string + description: Дата и время выполнения Операции СБП B2B + format: date-time + example: 2022-05-26T09:09:32Z + payerInfo: + $ref: '#/components/schemas/ClientInfo_2' + recipientInfo: + $ref: '#/components/schemas/ClientInfo_2' + description: Информация о входящем платеже + example: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001289" + amount: 1000000 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + payeeAccount: "40702810901400001130" + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + timestamp: 2022-05-26T09:09:32Z + GetOutgoingPaymentsResponse: + required: + - payments + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + payments: + type: array + items: + $ref: '#/components/schemas/OutgoingPayment' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + payments: + - amount: 1000000 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001130" + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + commission: 100 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + status: COMPLETE + timestamp: 2022-05-26T09:09:32Z + - amount: 1000000 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001130" + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + commission: 100 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + status: COMPLETE + timestamp: 2022-05-26T09:09:32Z + OutgoingPayment: + required: + - amount + - currency + - outgoingPaymentId + - payerAccount + - payerInfo + - paymentPurpose + - qrcId + - recipientInfo + - status + - taxAmount + type: object + properties: + outgoingPaymentId: + type: string + description: Идентификатор платежа в СБП B2B + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + nspkTransactionId: + maxLength: 32 + type: string + description: Идентификатор операции НСПК + example: B467FC50C59A469A9898AB7B05EE3F07 + status: + type: string + description: Статус платежа + example: COMPLETE + enum: + - SENDING_MESSAGE + - COMPLETE + amount: + minimum: 1 + type: integer + description: Сумма перевода в копейках + format: int64 + example: 1000000 + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + currency: + $ref: '#/components/schemas/Currency' + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет списания платежа + example: "40702810901400001130" + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + timestamp: + type: string + description: Дата и время выполнения Операции СБП B2B + format: date-time + example: 2022-05-26T09:09:32Z + commission: + maxLength: 15 + type: integer + description: Сумма комиссии в копейках + example: 100 + payerInfo: + $ref: '#/components/schemas/ClientInfo_2' + recipientInfo: + $ref: '#/components/schemas/ClientInfo_2' + description: Информация об исходящем платеже + example: + amount: 1000000 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810901400001130" + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + payerInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + currency: null + commission: 100 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + recipientInfo: + bik: "044525593" + bankCorrAccount: "30101810200000000593" + accountType: BBAN + name: OOO Ромашка + inn: "911006876365" + bankName: АО "АЛЬФА-БАНК" + status: COMPLETE + timestamp: 2022-05-26T09:09:32Z + OneStepExecuteOutgoingPayment: + required: + - amount + - client + - digestSignatures + - payerAccount + - paymentPurpose + - qrcId + - takeTax + type: object + properties: + client: + $ref: '#/components/schemas/ClientB2B' + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: + pattern: "^\\d{20}$" + type: string + description: Счет списания + example: "40702810100010000001" + amount: + minimum: 1 + type: integer + description: Сумма к зачислению в копейках + format: int64 + example: 1000000 + paymentPurpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Оплата по договору №123456789 от 01.09.2001 + takeTax: + type: boolean + description: | + Информация о взимании НДС. Возможные значения: + * `true` - облагается НДС; + * `false` - не облагается НДС + example: true + taxAmount: + minimum: 0 + type: integer + description: Сумма НДС в копейках + format: int64 + example: 200000 + digestSignatures: + type: array + items: + $ref: '#/components/schemas/Signature_2' + description: Данные для формирования и проведения платежа + example: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810100010000001" + amount: 1000000 + digestSignatures: + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + - poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + client: + partnerId: 214 + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + taxAmount: 200000 + takeTax: true + Signature_2: + required: + - base64Encoded + - signatureType + type: object + properties: + base64Encoded: + minLength: 1 + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: + minLength: 1 + type: string + description: Серийный номер сертификата + example: 61000366d11e143acbc03a56d70001000366d1 + signatureType: + type: string + description: Тип электронной подписи (РСА или КЭП) + example: RSA + enum: + - KEP + - RSA + poaNumber: + minLength: 1 + type: string + description: Номер машиночитаемой доверенности + example: DOVER_CBR_7702235133_20211102_1 + example: + poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + OneStepExecuteOutgoingPaymentResponse: + required: + - outgoingPaymentId + - qrcId + - status + type: object + properties: + outgoingPaymentId: + type: string + description: Идентификатор платежа в СБП B2B + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + status: + type: string + description: | + Статус платежа: + * `SENDING_MESSAGE` - платёж в обработке; + * `DRAFT` - черновик платежа зарегистрирован; + * `COMPLETE` - платёж выполнен; + * `ERROR` - платёж отклонен + example: COMPLETE + enum: + - SENDING_MESSAGE + - DRAFT + - COMPLETE + - ERROR + commission: + maxLength: 15 + type: integer + description: Сумма комиссии в копейках + example: 100 + description: Информация о статусе исходящего платежа с указанием комиссии + example: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + commission: 100 + status: COMPLETE + OutgoingPaymentStatus: + required: + - outgoingPaymentId + - qrcId + - status + type: object + properties: + outgoingPaymentId: + type: string + description: Идентификатор платежа в СБП B2B + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: + maxLength: 32 + minLength: 1 + type: string + description: Идентификатор платежной ссылки + example: AD1000038AQ1FG409KGACUQU5QRSH3FM + status: + type: string + description: | + Статус платежа: + * `SENDING_MESSAGE` - Платёж в обработке; + * `DRAFT` - Черновик платежа зарегистрирован; + * `COMPLETE` - Платёж выполнен; + * `ERROR` - Платёж отклонен + example: COMPLETE + enum: + - SENDING_MESSAGE + - DRAFT + - COMPLETE + - ERROR + description: Информация о статусе исходящего платежа + example: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + status: COMPLETE + inline_response_200: + type: object + properties: + merchantId: + type: string + example: + merchantId: merchantId + BusinessException: + title: BusinessException + required: + - detail + - instance + - status + - title + - type + type: object + properties: + type: + type: string + description: Код возникшей ошибки + detail: + type: string + description: Детализация ошибки + instance: + type: string + description: Урл по которому произошла ошибка + status: + type: integer + description: Код ошибки + title: + type: string + description: Описание ошибки + description: Информация о возникшей бизнес-ошибке + payments_search_body: + type: object + properties: + qrIds: + type: array + items: + type: string + PaymentInfoArray: + type: array + description: Массив платежей + items: + $ref: '#/components/schemas/PaymentInfo' + PaymentInfo: + type: object + properties: + account: + type: string + amount: + type: number + currency: + type: string + operationDate: + type: string + format: date-time + paymentId: + type: string + paymentStatus: + type: string + enum: + - SUCCESS + - DECLINED + - IN_PROGRESS + qrId: + type: string + example: + operationDate: 2000-01-23T04:56:07.000+00:00 + amount: 0.8008281904610115 + paymentId: paymentId + qrId: qrId + currency: currency + account: account + paymentStatus: SUCCESS + LinkDetail: + type: object + properties: + address: + type: string + description: Адрес магазина или точки + amount: + type: number + description: Сумма оплаты + bik: + type: string + description: БИК банка получателя + brandName: + type: string + description: Торговое наименование магазина или точки + inn: + type: string + description: ИНН получателя + legalName: + type: string + description: Наименование ЮЛ или ИП — получателя платежа + merchantId: + type: string + description: Идентификатор мерчанта + paymentPurpose: + type: string + description: Назначение платежа + qrId: + type: string + description: Идентификатор зарегистрированной ссылки в СБП + qrType: + type: string + description: "Тип ссылки: '01' — многоразовая, '02' — одноразовая" + receiverAccount: + type: string + description: Счет получателя + takeTax: + type: boolean + description: Признак взимания НДС + totalTaxAmount: + type: number + description: Сумма НДС + uip: + type: string + description: Уникальный идентификатор платежа + description: Информация о зарегистрированной платежной ссылке + example: + amount: 0.8008281904610115 + brandName: brandName + address: address + bik: bik + inn: inn + qrId: qrId + receiverAccount: receiverAccount + takeTax: true + legalName: legalName + merchantId: merchantId + qrType: qrType + paymentPurpose: paymentPurpose + totalTaxAmount: 6.027456183070403 + uip: uip + ReusableLinkRequest: + required: + - account + - currency + - merchantId + - takeTax + type: object + properties: + account: + type: string + description: Счет ЮЛ или ИП в банке + amount: + type: number + description: Сумма оплаты (необязательно — может быть задана плательщиком) + currency: + type: string + description: Код валюты по ISO-4217 + merchantId: + type: string + description: Идентификатор ТСП в СБП + paymentPurpose: + type: string + description: Назначение платежа + redirectUrl: + type: string + description: Ссылка возврата из банка в систему ТСП + takeTax: + type: boolean + description: Признак взимания НДС + totalTaxAmount: + type: number + description: Сумма НДС + description: Запрос на регистрацию многоразовой платежной ссылки + example: + amount: 0.8008281904610115 + redirectUrl: redirectUrl + merchantId: merchantId + currency: currency + paymentPurpose: paymentPurpose + totalTaxAmount: 6.027456183070403 + account: account + takeTax: true + LinkResponse: + type: object + properties: + payload: + type: string + description: Платежная ссылка для генерации QR-кода + qrId: + type: string + description: Идентификатор зарегистрированной ссылки + description: Ответ на регистрацию платежной ссылки + example: + payload: payload + qrId: qrId + OneTimeLinkRequest: + required: + - account + - amount + - currency + - merchantId + - orderId + - paymentPurpose + - takeTax + type: object + properties: + account: + type: string + description: Счет ЮЛ или ИП в банке + amount: + type: number + description: Сумма оплаты + currency: + type: string + description: Код валюты по ISO-4217 + merchantId: + type: string + description: Идентификатор ТСП в СБП + orderId: + type: string + description: "UUID оплаты, используется для идемпотентности" + paymentPurpose: + type: string + description: Назначение платежа + qrTtl: + type: number + description: Срок действия QR-кода в минутах + redirectUrl: + type: string + description: Ссылка возврата из банка в систему ТСП + takeTax: + type: boolean + description: Признак взимания НДС + totalTaxAmount: + type: number + description: "Сумма НДС, если takeTax = true" + uip: + type: string + description: Уникальный идентификатор платежа + description: Запрос на регистрацию одноразовой платежной ссылки + example: + amount: 0.8008281904610115 + redirectUrl: redirectUrl + merchantId: merchantId + orderId: orderId + qrTtl: 6.027456183070403 + currency: currency + paymentPurpose: paymentPurpose + totalTaxAmount: 1.4658129805029452 + uip: uip + account: account + takeTax: true + PhonePaymentReportResponse: + title: PhonePaymentReportResponse + required: + - client + - payments + type: object + properties: + client: + $ref: '#/components/schemas/BasePaymentResponse' + payments: + type: array + items: + $ref: '#/components/schemas/PhonePaymentReport' + example: + payments: + - eqTrnId: eqTrnId + amount: 6.027456183070403 + feeAccount: feeAccount + modifyDate: 2000-01-23T04:56:07.000+00:00 + errorDescription: errorDescription + payPackage: payPackage + nameCheck: true + inn: inn + transactionId: transactionId + nspkStatus: nspkStatus + sequence: sequence + feeAmount: 1.4658129805029452 + nspkBankName: nspkBankName + nspkTransactionId: nspkTransactionId + phone: phone + name: + middle: middle + last: last + first: first + orderInfo: + date: 2000-01-23T04:56:07.000+00:00 + number: number + recipientAccount: recipientAccount + recipientBic: recipientBic + account: account + nspkName: + middle: middle + last: last + first: first + createDate: 2000-01-23T04:56:07.000+00:00 + - eqTrnId: eqTrnId + amount: 6.027456183070403 + feeAccount: feeAccount + modifyDate: 2000-01-23T04:56:07.000+00:00 + errorDescription: errorDescription + payPackage: payPackage + nameCheck: true + inn: inn + transactionId: transactionId + nspkStatus: nspkStatus + sequence: sequence + feeAmount: 1.4658129805029452 + nspkBankName: nspkBankName + nspkTransactionId: nspkTransactionId + phone: phone + name: + middle: middle + last: last + first: first + orderInfo: + date: 2000-01-23T04:56:07.000+00:00 + number: number + recipientAccount: recipientAccount + recipientBic: recipientBic + account: account + nspkName: + middle: middle + last: last + first: first + createDate: 2000-01-23T04:56:07.000+00:00 + client: + b2cClientId: b2cClientId + partnerId: 0 + BasePaymentResponse: + title: BasePaymentResponse + required: + - partnerId + type: object + properties: + b2cClientId: + type: string + description: "Идентификатор клиента, от имени которого интегратором отпр\ + авляется платеж" + partnerId: + type: integer + description: Идентификатор партнера + format: int64 + example: + b2cClientId: b2cClientId + partnerId: 0 + PhonePaymentReport: + required: + - account + - amount + - createDate + - feeAmount + - inn + - modifyDate + - nspkBankName + - payPackage + - phone + - sequence + - transactionId + type: object + properties: + account: + type: string + description: Счет списания отправителя + inn: + type: string + description: ИНН отправителя + transactionId: + type: string + description: Уникальный идентификатор транзакции + sequence: + type: string + description: Идентификатор платежа плательщика внутри пакета + payPackage: + type: string + description: Идентификатор пакета + nspkTransactionId: + type: string + description: | + Код транзакции НСПК + nspkBankName: + type: string + description: Наименование банка получателя + nspkName: + $ref: '#/components/schemas/FioNspk' + name: + $ref: '#/components/schemas/Fio' + nameCheck: + type: boolean + description: Переданный в запросе флаг необходимости проверки совпадения + переданного ФИО получателя и зарегестрированного ФИО получателя в НСПК + eqTrnId: + type: string + description: Идентификатор платежа в банке-отправителе (EQ) + orderInfo: + $ref: '#/components/schemas/PhonePaymentReport_orderInfo' + phone: + type: string + description: Телефон получателя + amount: + type: number + description: Сумма платежа + feeAccount: + type: string + description: Счет списания комиссии + feeAmount: + type: number + description: Сумма комиссии платежа + createDate: + type: string + description: Дата/время создания платежа + format: date-time + modifyDate: + type: string + description: Дата/время изменения платежа + format: date-time + nspkStatus: + type: string + description: Статус платежа в НСПК + errorDescription: + type: string + description: Описание ошибки платежа + example: + eqTrnId: eqTrnId + amount: 6.027456183070403 + feeAccount: feeAccount + modifyDate: 2000-01-23T04:56:07.000+00:00 + errorDescription: errorDescription + payPackage: payPackage + nameCheck: true + inn: inn + transactionId: transactionId + nspkStatus: nspkStatus + sequence: sequence + feeAmount: 1.4658129805029452 + nspkBankName: nspkBankName + nspkTransactionId: nspkTransactionId + phone: phone + name: + middle: middle + last: last + first: first + orderInfo: + date: 2000-01-23T04:56:07.000+00:00 + number: number + recipientAccount: recipientAccount + recipientBic: recipientBic + account: account + nspkName: + middle: middle + last: last + first: first + createDate: 2000-01-23T04:56:07.000+00:00 + FioNspk: + type: object + properties: + last: + type: string + description: Фамилия + first: + type: string + description: Имя + middle: + type: string + description: Отчество + description: ФИО получателя в НСПК + example: + middle: middle + last: last + first: first + Fio: + type: object + properties: + last: + type: string + description: Фамилия + first: + type: string + description: Имя + middle: + type: string + description: Отчество + description: ФИО получателя + example: + middle: middle + last: last + first: first + Error_1: + required: + - error + - error_description + type: object + properties: + error: + type: string + description: Код ошибки + error_description: + type: string + description: Описание ошибки + PhonePaymentRequest: + required: + - account + - client + - inn + - payments + - signedBody + - total + type: object + properties: + signedBody: + type: string + description: Подписанное ЭЦП тело запроса + client: + $ref: '#/components/schemas/BasePaymentResponse' + inn: + type: string + description: ИНН отправителя + account: + pattern: "\\d{20}" + type: string + description: Номер счета отправителя + total: + type: number + description: Общая сумма платежей в пакете + nameCheck: + type: boolean + description: Флаг необходимости проверки совпадения переданного ФИО получателя + и зарегестрированного ФИО получателя в НСПК + payments: + type: array + items: + $ref: '#/components/schemas/PhonePaymentRequestRecipient' + example: + total: 0.8008281904610115 + nameCheck: true + payments: + - sequence: sequence + amount: 6.027456183070403 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + ric: 1 + paymentDescription: paymentDescription + - sequence: sequence + amount: 6.027456183070403 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + ric: 1 + paymentDescription: paymentDescription + inn: inn + client: + b2cClientId: b2cClientId + partnerId: 0 + signedBody: signedBody + account: account + PhonePaymentRequestRecipient: + required: + - amount + - nspkBankId + - paymentDescription + - phone + - ric + - sequence + type: object + properties: + name: + $ref: '#/components/schemas/Fio' + amount: + type: number + description: Сумма платежа + nspkBankId: + type: string + description: ID банка получателя + phone: + type: string + description: Телефон получателя + sequence: + type: string + description: |- + Идентификатор платежа внутри пакета. + Формируется потребителем сервиса b2cpay. + paymentDescription: + type: string + description: Описание платежа + ric: + type: integer + description: Код вида дохода + example: + sequence: sequence + amount: 6.027456183070403 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + ric: 1 + paymentDescription: paymentDescription + PhonePaymentResponse: + required: + - client + - payPackage + - payments + type: object + properties: + client: + $ref: '#/components/schemas/BasePaymentResponse' + payPackage: + type: string + description: Уникальный идентификатор пакета платежей + payments: + type: array + items: + $ref: '#/components/schemas/PhonePaymentResponseRecipient' + example: + payPackage: payPackage + payments: + - feeAmount: 6.027456183070403 + sequence: sequence + amount: 0.8008281904610115 + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + ric: 1 + transactionId: transactionId + createDate: 2000-01-23T04:56:07.000+00:00 + paymentDescription: paymentDescription + - feeAmount: 6.027456183070403 + sequence: sequence + amount: 0.8008281904610115 + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + ric: 1 + transactionId: transactionId + createDate: 2000-01-23T04:56:07.000+00:00 + paymentDescription: paymentDescription + client: + b2cClientId: b2cClientId + partnerId: 0 + PhonePaymentResponseRecipient: + required: + - amount + - createDate + - feeAmount + - paymentDescription + - phone + - ric + - sequence + - transactionId + type: object + properties: + amount: + type: number + description: Сумма платежа + feeAmount: + type: number + description: Сумма комиссии платежа + transactionId: + type: string + description: Уникальный идентификатор транзакции + phone: + type: string + description: Телефон получателя + sequence: + type: string + description: Идентификатор платежа от внешней системы. Повторяет пришедший + в запросе параметр Sequence + createDate: + type: string + description: Дата/Время создания платежа + format: date-time + paymentDescription: + type: string + description: Описание платежа + name: + $ref: '#/components/schemas/Fio' + nameCheck: + type: boolean + description: Переданный в запросе флаг необходимости проверки совпадения + переданного ФИО получателя и зарегестрированного ФИО получателя в НСПК + ric: + type: integer + description: Код вида дохода + example: + feeAmount: 6.027456183070403 + sequence: sequence + amount: 0.8008281904610115 + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + ric: 1 + transactionId: transactionId + createDate: 2000-01-23T04:56:07.000+00:00 + paymentDescription: paymentDescription + PhonePaymentCheckRequest: + required: + - client + - payments + type: object + properties: + client: + $ref: '#/components/schemas/BasePaymentResponse' + nameCheck: + type: boolean + description: Флаг необходимости проверки совпадения переданного ФИО получателя + и зарегестрированного ФИО получателя в НСПК + payments: + type: array + items: + $ref: '#/components/schemas/PhonePaymentCheckRecipient' + example: + nameCheck: true + payments: + - amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + - amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + client: + b2cClientId: b2cClientId + partnerId: 0 + PhonePaymentCheckRecipient: + required: + - amount + - nspkBankId + - phone + type: object + properties: + amount: + type: number + description: Сумма платежа + nspkBankId: + type: string + description: ID банка получателя + phone: + type: string + description: Телефон получателя + name: + $ref: '#/components/schemas/Fio' + example: + amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + name: + middle: middle + last: last + first: first + PhonePaymentCheckResponse: + required: + - checkId + - client + type: object + properties: + checkId: + type: string + description: "Уникальный идентификатор запроса на проверку, по которому\ + \ в дальнейшем возможно получение статуса проверки" + client: + $ref: '#/components/schemas/BasePaymentResponse' + example: + client: + b2cClientId: b2cClientId + partnerId: 0 + checkId: checkId + PhonePaymentCheckStatusResponse: + title: PhonePaymentCheckStatusResponse + required: + - client + - payments + type: object + properties: + client: + $ref: '#/components/schemas/BasePaymentResponse' + payments: + type: array + items: + $ref: '#/components/schemas/PhonePaymentCheckStatusRecipient' + example: + payments: + - amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + error: error + nspkName: + middle: middle + last: last + first: first + status: status + - amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + error: error + nspkName: + middle: middle + last: last + first: first + status: status + client: + b2cClientId: b2cClientId + partnerId: 0 + PhonePaymentCheckStatusRecipient: + required: + - amount + - nspkBankId + - phone + - status + type: object + properties: + amount: + type: number + description: Сумма платежа + nspkBankId: + type: string + description: ID банка получателя + nspkName: + $ref: '#/components/schemas/FioNspk' + name: + $ref: '#/components/schemas/Fio' + nameCheck: + type: boolean + description: Переданный в запросе флаг необходимости проверки совпадения + переданного ФИО получателя и зарегестрированного ФИО получателя в НСПК + phone: + type: string + description: Телефон получателя + status: + type: string + description: Результат проверки возможности отправки платежа по реквизитам + error: + type: string + description: Ошибка + example: + amount: 0.8008281904610115 + nspkBankId: nspkBankId + phone: phone + nameCheck: true + name: + middle: middle + last: last + first: first + error: error + nspkName: + middle: middle + last: last + first: first + status: status + BanksResponse: + title: BanksResponse + required: + - bankId + - bankName + type: object + properties: + bankId: + type: string + description: Идентификатор банка НСПК + bankName: + type: string + description: Наименование банка НСПК + example: + bankId: bankId + bankName: bankName + ClientInnResponse: + title: ClientInnResponse + required: + - client + - inn + type: object + properties: + client: + $ref: '#/components/schemas/BasePaymentResponse' + inn: + type: string + description: ИНН клиента из запроса + example: + inn: inn + client: + b2cClientId: b2cClientId + partnerId: 0 + CreditOffers: + title: Кредитные предложения + required: + - offers + type: object + properties: + offers: + title: Массив предложений + type: array + items: + $ref: '#/components/schemas/CreditOffer' + default: [] + example: + offers: + - creditProduct: + cardInfo: + gracePeriod: 5 + limit: 5.637376656633329 + currency: currency + creditInfo: + period: 1 + rate: 6.027456183070403 + webViewUrl: webViewUrl + id: 0.8008281904610115 + title: title + - creditProduct: + cardInfo: + gracePeriod: 5 + limit: 5.637376656633329 + currency: currency + creditInfo: + period: 1 + rate: 6.027456183070403 + webViewUrl: webViewUrl + id: 0.8008281904610115 + title: title + CreditOffer: + title: Объект кредитного предложения + required: + - id + - title + type: object + properties: + id: + type: number + description: Идентификатор кредитного предложения + format: decimal + title: + type: string + description: Тип предложения + webViewUrl: + type: string + description: Ссылка на открытие кредитного предложения в мобильном приложении + creditProduct: + $ref: '#/components/schemas/CreditProduct' + example: + creditProduct: + cardInfo: + gracePeriod: 5 + limit: 5.637376656633329 + currency: currency + creditInfo: + period: 1 + rate: 6.027456183070403 + webViewUrl: webViewUrl + id: 0.8008281904610115 + title: title + CreditProduct: + title: Кредитный продукт + type: object + properties: + creditInfo: + $ref: '#/components/schemas/CreditInfo' + cardInfo: + $ref: '#/components/schemas/CardInfo' + limit: + type: number + description: Лимит по кредитному предложению + format: double + currency: + type: string + description: Валюта + example: + cardInfo: + gracePeriod: 5 + limit: 5.637376656633329 + currency: currency + creditInfo: + period: 1 + rate: 6.027456183070403 + CreditInfo: + title: Информация о кредитном предложении + type: object + properties: + rate: + type: number + description: Ставка + format: decimal + period: + type: integer + description: Срок + example: + period: 1 + rate: 6.027456183070403 + CardInfo: + title: Данные по картам + type: object + properties: + gracePeriod: + type: integer + description: Грейс-период + example: + gracePeriod: 5 + GetStatisOrDynamicQRc: + required: + - qrcType + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + qrcType: + type: string + description: | + Тип запрашиваемого QR-кода: + * `01` - для статического QR-кода; + * `02` - для динамического QR-кода. + example: "02" + enum: + - "01" + - "02" + paymentPurpose: + type: string + description: Назначение платежа + example: Назначение платежа + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни платежной ссылки в минутах + example: 4320 + default: 4320 + queryData: + $ref: '#/components/schemas/QueryData' + subscriptionPurpose: + type: string + description: Цель привязки счета + example: Подписка на оплату интернета 500р./мес. + redirectUrl: + type: string + description: Cсылка для автоматического возврата в приложение или на сайт + ТСП + example: https://exampletsp.io/qwertyui + messageId: + type: string + description: Уникальный идентификатор сообщения + example: + amount: 10000 + redirectUrl: https://exampletsp.io/qwertyui + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + messageId: messageId + currency: RUR + termNo: "9008056701" + paymentPurpose: Назначение платежа + subscriptionPurpose: Подписка на оплату интернета 500р./мес. + ttl: 4320 + qrcType: "02" + Currency_1: + type: string + description: | + Код валюты: `RUR` - рубли + example: RUR + enum: + - RUR + QueryData: + type: object + properties: + notificationUrl: + type: string + description: Полный URL для получения уведомления о финальном статусе операции + example: http://10.8.18.33:9017/sbp-payment/agent/status + description: Данные запроса + example: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + GetQRcResponse: + required: + - image + - payload + - payrrn + - qrcId + - status + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "90080567" + payload: + type: string + description: Платёжная ссылка + example: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + image: + type: string + description: Изображение QR-кода в формате Base64 + example: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + status: + type: string + description: Статус регистрации Платёжной или Информационной ссылки СБП + example: CREATED + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + payrrn: "000000020512" + termNo: "90080567" + status: CREATED + GetQRcStatusResponse: + required: + - amount + - creditDatePos + - payrrn + - qrcId + - status + - termNo + - trxDT + - trxId + type: object + properties: + creditDatePos: + type: string + description: "Дата операции, установленная Банком" + format: date + example: 2022-12-19 + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + status: + type: string + description: | + Статус оплаты QR-кода в НСПК: + * `NTST` - операции по QR-коду не существует; + * `RCVD` - операция в обработке; + * `ACWP` - операция завершена успешно; + * `RJCT` - операция отклонена. + example: ACWP + enum: + - NTST + - RCVD + - ACWP + - RJCT + trxId: + type: string + description: Уникальный идентификатор платежа в НСПК + example: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + trxDT: + type: string + description: Дата и время отменяемого платежа + format: date-time + example: 2022-12-19T07:40:28Z + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + amount: 10000 + trxDT: 2022-12-19T07:40:28Z + creditDatePos: 2022-12-19T00:00:00.000+00:00 + payrrn: "000000020512" + currency: RUR + termNo: "9008056701" + trxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + status: ACWP + GetQRcSubscriptionRequest: + required: + - queryData + - subscriptionPurpose + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + subscriptionPurpose: + type: string + description: Цель привязки счета + example: Подписка на оплату интернета 500р./мес. + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни платежной ссылки в минутах + example: 4320 + default: 4320 + queryData: + $ref: '#/components/schemas/GetQRcSubscriptionRequest_queryData' + redirectUrl: + type: string + description: Содержит ссылку для автоматического возврата в приложение или + на интернет страницу + example: https://exampletsp.io/qwertyui + example: + redirectUrl: https://exampletsp.io/qwertyui + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + termNo: "9008056701" + subscriptionPurpose: Подписка на оплату интернета 500р./мес. + ttl: 4320 + GetQRcSubscriptionRequest_queryData: + required: + - notificationUrl + type: object + properties: + notificationUrl: + type: string + description: Полный URL для получения уведомления о финальном статусе операции + example: http://10.8.18.33:9017/sbp-payment/agent/status + description: Данные запроса + example: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + GetQRcSubscriptionResponse: + required: + - payload + - payrrn + - qrcId + type: object + properties: + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + payload: + type: string + description: Платежная ссылка + example: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + payrrn: "000000020512" + PaymentFromBindedAccountRequest: + required: + - amount + - currency + - paymentPurpose + - senderMemberId + - subscriptionToken + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + paymentPurpose: + type: string + description: Назначение платежа + example: Назначение платежа + ttl: + maximum: 129600 + minimum: 1 + type: integer + description: Срок жизни платежной ссылки в минутах + example: 4320 + default: 4320 + queryData: + $ref: '#/components/schemas/QueryData' + redirectUrl: + type: string + description: Cсылка для автоматического возврата в приложение или на сайт + ТСП + example: https://exampletsp.io/qwertyui + subscriptionToken: + type: string + description: Идентификатор Привязки счета + example: 70LSS7DN18SJQRS10006DNPKLJL24B05 + senderMemberId: + type: string + description: Идентификатор банка Плательщика + example: "100000000001" + messageId: + type: string + description: Уникальный идентификатор сообщения + description: Платеж с привязанного счета + example: + amount: 10000 + redirectUrl: https://exampletsp.io/qwertyui + subscriptionToken: 70LSS7DN18SJQRS10006DNPKLJL24B05 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + messageId: messageId + currency: RUR + termNo: "9008056701" + paymentPurpose: Назначение платежа + ttl: 4320 + senderMemberId: "100000000001" + PaymentFromBindedAccountResponse: + required: + - image + - payload + - payrrn + - qrcId + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "90080567" + payload: + type: string + description: Платёжная ссылка + example: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + image: + type: string + description: Изображение QR-кода в формате Base64 + example: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + payrrn: "000000020512" + termNo: "90080567" + QRcRefundRequest: + required: + - amount + - currency + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AD100074066RHM939FE9OQKR0TQ63HB6 + originalTrxId: + type: string + description: Идентификатор исходной операции СБП C2B + example: A003610425360300b4ubOp6511E4F998 + originalTrxDT: + type: string + description: Дата и время отменяемого платежа + format: date-time + example: 2022-12-19T07:40:28Z + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + queryData: + $ref: '#/components/schemas/QueryData' + messageId: + type: string + description: Уникальный идентификатор сообщения + example: + qrcId: AD100074066RHM939FE9OQKR0TQ63HB6 + originalTrxId: A003610425360300b4ubOp6511E4F998 + amount: 10000 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + payrrn: "000000020512" + messageId: messageId + currency: RUR + termNo: "9008056701" + originalTrxDT: 2022-12-19T07:40:28Z + QRcRefundResponse: + required: + - amount + - currency + - payrrn + - termNo + - trxDT + - trxId + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + trxId: + type: string + description: Референсный идентификатор операции + example: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + trxDT: + type: string + description: Дата и время платежа + format: date-time + example: 2022-12-19T07:40:28Z + messageId: + type: string + description: Уникальный идентификатор сообщения + example: + amount: 10000 + trxDT: 2022-12-19T07:40:28Z + payrrn: "000000020512" + messageId: messageId + currency: RUR + termNo: "9008056701" + trxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + GetQRcRefundStatusResponse: + required: + - amount + - originalQRcId + - originalTrxId + - payerId + - status + - termNo + - trxDT + - trxId + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + batchId: + type: string + description: Уникальный идентификатор смены + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + url: + type: string + description: Полный URL для получения уведомления о финальном статусе операции + example: http://10.8.18.33:9017/sbp-payment/agent/status + originalQRcId: + pattern: "^.{32}$" + type: string + description: Идентификатор зарегистрированной платёжной ссылки СБП + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + originalTrxId: + type: string + description: Уникальный идентификатор платежа в НСПК + example: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + payerId: + type: string + description: Маскированный номер телефона получателя (плательщика в исходной + операции C2B) + example: '*******5526' + status: + type: string + description: | + Статус операции возврата СБП: + * `NTST` - статус операции неизвестен; + * `ACWP` - операция завершена успешно; + * `RJCT` - операция отклонена. + example: ACWP + enum: + - NTST + - ACWP + - RJCT + trxId: + type: string + description: Уникальный идентификатор операции возврата в НСПК + example: 1SA32XD5F6G78J9K0HC4S5C6D4V7D5J2 + trxDT: + type: string + description: Дата и время выполнения операции СБП + format: date-time + example: 2020-07-28T11:45:31Z + messageId: + type: string + description: Уникальный идентификатор сообщения + description: Статус запроса возврата средств по операции СБП + example: + originalQRcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + originalTrxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + amount: 10000 + trxDT: 2020-07-28T11:45:31Z + payerId: '*******5526' + messageId: messageId + termNo: "9008056701" + batchId: batchId + trxId: 1SA32XD5F6G78J9K0HC4S5C6D4V7D5J2 + url: http://10.8.18.33:9017/sbp-payment/agent/status + status: ACWP + CashQRcsRegistrationRequest: + type: object + properties: + mediaType: + type: string + description: Формат получаемого файла + example: image/png + width: + type: string + description: Ширина изображения QR-кода + example: "200" + height: + type: string + description: Высота изображения QR-кода + example: "200" + redirectUrl: + type: string + description: Содержит ссылку для автоматического возврата в приложение или + на сайт ТСП + example: https://exampletsp.io/qwertyui + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + redirectUrl: https://exampletsp.io/qwertyui + width: "200" + mediaType: image/png + height: "200" + CashQRcsRegistrationResponse: + required: + - payload + - qrcId + - status + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + payload: + type: string + description: Платежная ссылка + example: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + status: + type: string + description: "Статус кассовой ссылки, полученный из НСПК" + example: CREATED + image: + $ref: '#/components/schemas/Image' + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + image: + mediaType: image/png + content: iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAArvElEQVR4Xu2d/bOvVXne/ + /B2Pwbvw1OqlrAAAAAElFTkSuQmCC + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + termNo: "9008056701" + status: CREATED + Image: + type: object + properties: + mediaType: + type: string + description: Формат получаемого файла + example: image/png + content: + type: string + description: Base64-кодированные данные файла изображения QR-кода + example: iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAArvElEQVR4Xu2d/bOvVXne/ + /B2Pwbvw1OqlrAAAAAElFTkSuQmCC + example: + mediaType: image/png + content: iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAArvElEQVR4Xu2d/bOvVXne/ + /B2Pwbvw1OqlrAAAAAElFTkSuQmCC + CashQRcsActivationRequest: + required: + - amount + type: object + properties: + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + paymentPurpose: + type: string + description: Назначение платежа + example: "Капучино 300 мл 1 шт., булочка 1 шт." + ttl: + maximum: 20 + minimum: 1 + type: integer + description: Период использования кассовой ссылки в минутах + example: 5 + default: 5 + queryData: + $ref: '#/components/schemas/QueryData' + example: + amount: 10000 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + currency: RUR + paymentPurpose: "Капучино 300 мл 1 шт., булочка 1 шт." + ttl: 5 + CashQRcsActivationResponse: + required: + - amount + - paramsId + - payrrn + - qrcId + - termNo + type: object + properties: + termNo: + type: string + description: Уникальный идентификатор терминала + example: "9008056701" + paramsId: + type: string + description: Идентификатор параметров ссылки СБП + example: AP5GK3L276DN8PDR8ON1LF4RVOL44444 + qrcId: + pattern: "^.{32}$" + type: string + description: Идентификатор QR-кода + example: AS1000670LSS7DN18SJQDNP4B05KLJL2 + amount: + maximum: 100000000 + minimum: 1 + type: integer + description: Сумма операции СБП C2B в копейках + example: 10000 + currency: + $ref: '#/components/schemas/Currency_1' + paymentPurpose: + type: string + description: Назначение платежа + example: Назначение платежа + payrrn: + type: string + description: Референсный идентификатор запроса + example: "000000020512" + example: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + amount: 10000 + paramsId: AP5GK3L276DN8PDR8ON1LF4RVOL44444 + payrrn: "000000020512" + currency: RUR + termNo: "9008056701" + paymentPurpose: Назначение платежа + CreateAccountsApplicationRequest: + required: + - applicationCreatedAt + - applicationId + - bic + - contractNumber + - currency + - registryCreatedAt + - registryNumber + - rowsCount + type: object + properties: + applicationId: + maxLength: 35 + type: string + description: Внешний идентификатор заявления на открытие личного счета + applicationCreatedAt: + type: string + description: Дата создания запроса + format: date-time + registryNumber: + type: string + description: Номер реестра + registryCreatedAt: + type: string + description: Дата создания реестра + format: date-time + currency: + type: string + description: Валюта зарплаты + enum: + - RUR + contractNumber: + type: string + description: Номер договора зарплатного проекта + bic: + type: string + description: БИК + organization: + $ref: '#/components/schemas/OrganizationRequest' + rowsCount: + type: integer + description: Количество сотрудников + employees: + type: array + items: + $ref: '#/components/schemas/EmployeeRequest' + example: + registryNumber: registryNumber + rowsCount: 0 + organization: + country: country + address: address + inn: inn + fullname: fullname + accountNumber: accountNumber + registryCreatedAt: 2000-01-23T04:56:07.000+00:00 + contractNumber: contractNumber + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + currency: RUR + applicationId: applicationId + employees: + - bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + bankBranchCode: bankBranchCode + bkiSharingAllowed: true + cardInfo: + embossedText: + firstName: firstName + lastName: lastName + salutation: salutation + salaryType: salaryType + type: type + currencyCode: currencyCode + identityDocument: + number: number + series: series + issuerName: issuerName + typeName: typeName + issuerCode: issuerCode + issueDate: 2000-01-23 + typeCode: typeCode + employmentDate: 2000-01-23 + sex: sex + citizenship: citizenship + birthDate: 2000-01-23 + npp: npp + firstName: firstName + birthPlace: + cityShort: cityShort + locationFull: locationFull + cityFull: cityFull + regionFull: regionFull + districtFull: districtFull + regionShort: regionShort + locationShort: locationShort + districtShort: districtShort + mobileBank: mobileBank + personnelNumber: personnelNumber + mobilePhone: mobilePhone + salaryAmount: 6.027456183070403 + populationCategory: populationCategory + middleName: middleName + position: position + salaryCurrencyCode: salaryCurrencyCode + paymentDate: 2000-01-23 + contactPhone: contactPhone + resident: true + - bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + bankBranchCode: bankBranchCode + bkiSharingAllowed: true + cardInfo: + embossedText: + firstName: firstName + lastName: lastName + salutation: salutation + salaryType: salaryType + type: type + currencyCode: currencyCode + identityDocument: + number: number + series: series + issuerName: issuerName + typeName: typeName + issuerCode: issuerCode + issueDate: 2000-01-23 + typeCode: typeCode + employmentDate: 2000-01-23 + sex: sex + citizenship: citizenship + birthDate: 2000-01-23 + npp: npp + firstName: firstName + birthPlace: + cityShort: cityShort + locationFull: locationFull + cityFull: cityFull + regionFull: regionFull + districtFull: districtFull + regionShort: regionShort + locationShort: locationShort + districtShort: districtShort + mobileBank: mobileBank + personnelNumber: personnelNumber + mobilePhone: mobilePhone + salaryAmount: 6.027456183070403 + populationCategory: populationCategory + middleName: middleName + position: position + salaryCurrencyCode: salaryCurrencyCode + paymentDate: 2000-01-23 + contactPhone: contactPhone + resident: true + bic: bic + OrganizationRequest: + required: + - accountNumber + - address + - country + - fullname + - inn + type: object + properties: + fullname: + type: string + description: Полное название + country: + type: string + description: Страна + address: + type: string + description: Адрес + inn: + type: string + description: ИНН + accountNumber: + type: string + description: Номер счета + example: + country: country + address: address + inn: inn + fullname: fullname + accountNumber: accountNumber + EmployeeRequest: + required: + - bankBranchCode + - bankBranchOfficeCode + - birthDate + - citizenship + - firstName + - lastName + - mobileBank + - mobilePhone + - npp + - resident + - salaryCurrencyCode + - sex + type: object + properties: + npp: + type: string + description: НПП сотрудника (Идентификатор строки заявки на открытие ЛС + для одного сотрудника) + lastName: + type: string + description: Фамилия + firstName: + type: string + description: Имя + middleName: + type: string + description: Отчество + bankBranchCode: + type: string + description: Отделение банка + bankBranchOfficeCode: + type: string + description: Филиал отделения банка + birthDate: + type: string + description: Дата рождения + format: date + sex: + type: string + description: Пол + position: + type: string + description: Должность + salaryCurrencyCode: + type: string + description: Код валюты зарплаты + resident: + type: boolean + description: Резидент + citizenship: + type: string + description: Гражданство + populationCategory: + type: string + description: Категория населения + mobilePhone: + type: string + description: Мобильный телефон + mobileBank: + type: string + description: Мобильный банк + bkiSharingAllowed: + type: boolean + description: Разрешение передачи информации в бюро кредитных историй (БКИ) + для овердрафтных карт + personnelNumber: + type: string + description: Табельный номер + employmentDate: + type: string + description: Дата приёма на работу + format: date + salaryAmount: + type: number + description: Сумма зарплаты + paymentDate: + type: string + description: Дата выплаты + format: date + contactPhone: + type: string + description: Контактный телефон + cardInfo: + $ref: '#/components/schemas/CardInfoRequest' + identityDocument: + $ref: '#/components/schemas/IdentityDocumentRequest' + birthPlace: + $ref: '#/components/schemas/BirthPlaceRequest' + example: + bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + bankBranchCode: bankBranchCode + bkiSharingAllowed: true + cardInfo: + embossedText: + firstName: firstName + lastName: lastName + salutation: salutation + salaryType: salaryType + type: type + currencyCode: currencyCode + identityDocument: + number: number + series: series + issuerName: issuerName + typeName: typeName + issuerCode: issuerCode + issueDate: 2000-01-23 + typeCode: typeCode + employmentDate: 2000-01-23 + sex: sex + citizenship: citizenship + birthDate: 2000-01-23 + npp: npp + firstName: firstName + birthPlace: + cityShort: cityShort + locationFull: locationFull + cityFull: cityFull + regionFull: regionFull + districtFull: districtFull + regionShort: regionShort + locationShort: locationShort + districtShort: districtShort + mobileBank: mobileBank + personnelNumber: personnelNumber + mobilePhone: mobilePhone + salaryAmount: 6.027456183070403 + populationCategory: populationCategory + middleName: middleName + position: position + salaryCurrencyCode: salaryCurrencyCode + paymentDate: 2000-01-23 + contactPhone: contactPhone + resident: true + CardInfoRequest: + type: object + properties: + type: + type: string + description: Наименование карточного продукта + currencyCode: + type: string + description: Код валюты карты + embossedText: + $ref: '#/components/schemas/CardInfoRequest_embossedText' + salaryType: + type: string + description: Признак зарплатной карты 0 – незарплатная; 1 – зарплатная с + оплатой предприятием; 2 – 100% оплата держателем карты; 3 – долевая оплата + и предприятием и держателем карты + description: Информация о карте + example: + embossedText: + firstName: firstName + lastName: lastName + salutation: salutation + salaryType: salaryType + type: type + currencyCode: currencyCode + IdentityDocumentRequest: + required: + - issueDate + - issuerCode + - issuerName + - number + - series + - typeCode + - typeName + type: object + properties: + typeName: + type: string + description: Название типа документа + typeCode: + type: string + description: Код типа документа + series: + type: string + description: Серия + number: + type: string + description: Номер + issueDate: + type: string + description: Дата выдачи + format: date + issuerName: + type: string + description: Кем выдан + issuerCode: + type: string + description: Код подразделения + description: Сведения о документе удостоверяющем личность + example: + number: number + series: series + issuerName: issuerName + typeName: typeName + issuerCode: issuerCode + issueDate: 2000-01-23 + typeCode: typeCode + BirthPlaceRequest: + type: object + properties: + regionFull: + type: string + description: Регион (полн.) + regionShort: + type: string + description: Регион (сокр.) + districtFull: + type: string + description: Район (полн.) + districtShort: + type: string + description: Район (сокр.) + cityFull: + type: string + description: Город (полн.) + cityShort: + type: string + description: Город (сокр.) + locationFull: + type: string + description: Населенный пункт (полн.) + locationShort: + type: string + description: Населенный пункт (сокр.) + description: Сведения о месте рождения + example: + cityShort: cityShort + locationFull: locationFull + cityFull: cityFull + regionFull: regionFull + districtFull: districtFull + regionShort: regionShort + locationShort: locationShort + districtShort: districtShort + CreateAccountsApplicationResponse: + required: + - applicationCreatedAt + - applicationId + - contractNumber + - orderType + - registryCreatedAt + - registryNumber + - status + type: object + properties: + orderType: + type: string + description: Тип заявки + applicationId: + maxLength: 35 + type: string + description: Внешний ID запроса + applicationCreatedAt: + type: string + description: Дата создания запроса + format: date-time + registryNumber: + type: string + description: Номер реестра + registryCreatedAt: + type: string + description: Дата создания реестра + format: date-time + status: + type: string + description: Статус сообщения (заявки на открытие ЛС) + statusDescription: + type: string + description: Описание статуса сообщения (заявки на открытие ЛС) + contractNumber: + type: string + description: Номер договора зарплатного проекта + organization: + $ref: '#/components/schemas/OrganizationResponse' + rowsCount: + type: integer + description: Количество сотрудников + employees: + type: array + items: + $ref: '#/components/schemas/EmployeeResponse' + example: + orderType: orderType + statusDescription: statusDescription + registryNumber: registryNumber + rowsCount: 0 + organization: + country: country + inn: inn + fullname: fullname + registryCreatedAt: 2000-01-23T04:56:07.000+00:00 + contractNumber: contractNumber + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + applicationId: applicationId + employees: + - lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + - lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + status: status + OrganizationResponse: + required: + - country + - fullname + - inn + type: object + properties: + fullname: + type: string + description: Полное название + country: + type: string + description: Страна + inn: + type: string + description: ИНН + example: + country: country + inn: inn + fullname: fullname + EmployeeResponse: + required: + - firstName + - lastName + - npp + type: object + properties: + npp: + type: string + description: НПП сотрудника (Идентификатор строки заявки на открытие ЛС + для одного сотрудника) + lastName: + type: string + description: Фамилия + firstName: + type: string + description: Имя + middleName: + type: string + description: Отчество + account: + $ref: '#/components/schemas/AccountResponse_2' + example: + lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + AccountResponse_2: + required: + - number + - status + type: object + properties: + number: + type: string + description: Открытый лицевой счёт сотрудника + status: + type: string + description: Статус открытия ЛС сотрудника + statusDescription: + type: string + description: Описание статуса открытия ЛС сотрудника + example: + number: number + statusDescription: statusDescription + status: status + GetAccountsApplicationResponse: + required: + - applicationCreatedAt + - applicationId + - contractNumber + - orderType + - registryCreatedAt + - registryNumber + - status + type: object + properties: + orderType: + type: string + description: Тип заявки + applicationId: + type: string + description: Внешний ID запроса + applicationCreatedAt: + type: string + description: Дата создания запроса + format: date-time + registryNumber: + type: string + description: Номер реестра + registryCreatedAt: + type: string + description: Дата создания реестра + format: date-time + status: + type: string + description: Статус сообщения (заявки на открытие ЛС) + statusDescription: + type: string + description: Описание статуса сообщения (заявки на открытие ЛС) + contractNumber: + type: string + description: Номер договора зарплатного проекта + organization: + $ref: '#/components/schemas/OrganizationResponse' + rowsCount: + type: integer + description: Количество сотрудников + employees: + type: array + items: + $ref: '#/components/schemas/EmployeeResponse_1' + example: + orderType: orderType + statusDescription: statusDescription + registryNumber: registryNumber + rowsCount: 0 + organization: + country: country + inn: inn + fullname: fullname + registryCreatedAt: 2000-01-23T04:56:07.000+00:00 + contractNumber: contractNumber + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + applicationId: applicationId + employees: + - lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + - lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + status: status + EmployeeResponse_1: + required: + - firstName + - lastName + - npp + type: object + properties: + npp: + type: string + description: НПП сотрудника (Идентификатор строки заявки на открытие ЛС + для одного сотрудника) + lastName: + type: string + description: Фамилия + firstName: + type: string + description: Имя + middleName: + type: string + description: Отчество + account: + $ref: '#/components/schemas/AccountResponse_2' + example: + lastName: lastName + firstName: firstName + middleName: middleName + account: + number: number + statusDescription: statusDescription + status: status + npp: npp + CreatePayrollApplicationRequest: + required: + - admissionValue + - applicationCreatedAt + - applicationId + - bic + - contractNumber + - payrollId + - registryCreatedAt + - registryNumber + - rowsCount + - totalAmount + type: object + properties: + applicationId: + maxLength: 35 + type: string + description: Внешний ID запроса + applicationCreatedAt: + type: string + description: Дата создания запроса + format: date-time + totalAmount: + type: number + description: Общая сумма к выплате + payrollId: + maxLength: 35 + type: string + description: Идентификатор ведомости + admissionValue: + type: string + description: Код зачисления + registryNumber: + type: string + description: Номер реестра + registryCreatedAt: + type: string + description: Дата создания реестра + format: date + contractNumber: + type: string + description: Номер договора зарплатного проекта + bic: + type: string + description: БИК + organization: + $ref: '#/components/schemas/OrganizationRequest_1' + rowsCount: + type: integer + description: Количество сотрудников + employees: + type: array + items: + $ref: '#/components/schemas/EmployeeRequest_1' + example: + totalAmount: 0.8008281904610115 + registryNumber: registryNumber + rowsCount: 6 + organization: + inn: inn + fullname: fullname + accountNumber: accountNumber + registryCreatedAt: 2000-01-23 + contractNumber: contractNumber + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + admissionValue: admissionValue + payrollId: payrollId + applicationId: applicationId + employees: + - bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + firstName: firstName + retentionAmount: 5.637376656633329 + bankBranchCode: bankBranchCode + amount: 5.962133916683182 + bankBic: bankBic + middleName: middleName + currency: RUR + rowNumber: 1.4658129805029452 + accountNumber: accountNumber + rowId: rowId + - bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + firstName: firstName + retentionAmount: 5.637376656633329 + bankBranchCode: bankBranchCode + amount: 5.962133916683182 + bankBic: bankBic + middleName: middleName + currency: RUR + rowNumber: 1.4658129805029452 + accountNumber: accountNumber + rowId: rowId + bic: bic + OrganizationRequest_1: + required: + - accountNumber + - fullname + - inn + type: object + properties: + fullname: + type: string + description: Полное название + inn: + type: string + description: ИНН + accountNumber: + type: string + description: Номер счета + example: + inn: inn + fullname: fullname + accountNumber: accountNumber + EmployeeRequest_1: + required: + - accountNumber + - amount + - bankBranchCode + - bankBranchOfficeCode + - currency + - firstName + - lastName + - rowId + - rowNumber + type: object + properties: + rowId: + maxLength: 35 + type: string + description: Идентификатор строки ведомости (внутренний) + rowNumber: + type: number + description: Номер строки в ведомости в банк + lastName: + type: string + description: Фамилия + firstName: + type: string + description: Имя + middleName: + type: string + description: Отчество + bankBranchCode: + type: string + description: Отделение банка + bankBranchOfficeCode: + type: string + description: Филиал отделения банка + bankBic: + type: string + description: "БИК банка, в котором открыт счёт, в случае, если он отлича\ + ется от банка зарплатного проекта" + accountNumber: + type: string + description: Номер лицевого счета + amount: + type: number + description: К выплате + currency: + type: string + description: Цифровой код валюты + enum: + - RUR + retentionAmount: + type: number + description: Удержание с зарплаты (Взыскание) + example: + bankBranchOfficeCode: bankBranchOfficeCode + lastName: lastName + firstName: firstName + retentionAmount: 5.637376656633329 + bankBranchCode: bankBranchCode + amount: 5.962133916683182 + bankBic: bankBic + middleName: middleName + currency: RUR + rowNumber: 1.4658129805029452 + accountNumber: accountNumber + rowId: rowId + CreatePayrollApplicationResponse: + required: + - applicationCreatedAt + - applicationId + type: object + properties: + applicationId: + maxLength: 35 + type: string + description: Внешний ID запроса + applicationCreatedAt: + type: string + format: date-time + originalMessage: + $ref: '#/components/schemas/CreatePayrollApplicationResponse_originalMessage' + payroll: + $ref: '#/components/schemas/CreatePayrollApplicationResponse_payroll' + example: + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + payroll: + reason: reason + id: id + accrual: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + status: status + applicationId: applicationId + originalMessage: + createdAt: 2000-01-23T04:56:07.000+00:00 + reason: reason + id: id + status: status + GetPayrollApplicationResponse: + required: + - applicationCreatedAt + - applicationId + type: object + properties: + applicationId: + type: string + description: Внешний ID запроса + applicationCreatedAt: + type: string + description: Дата создания запроса + format: date-time + originalMessage: + $ref: '#/components/schemas/CreatePayrollApplicationResponse_originalMessage' + payroll: + $ref: '#/components/schemas/GetPayrollApplicationResponse_payroll' + example: + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + payroll: + reason: reason + id: id + accrual: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + status: status + applicationId: applicationId + originalMessage: + createdAt: 2000-01-23T04:56:07.000+00:00 + reason: reason + id: id + status: status + ClientSubscriptions: + type: array + items: + $ref: '#/components/schemas/ClientSubscription' + ClientSubscription: + type: object + properties: + serviceCode: + type: string + description: Код подключенного сервиса + state: + type: string + description: Статуc подписки (старый) + activatedAt: + type: string + description: Дата и время активации подписки в формате timestamp + format: date-time + nextFeeAt: + type: string + description: Дата следующего платежа по подписке в формате YYYY-MM-DD + format: date + disabledAt: + type: string + description: Дата фактического отключения подписки в формате YYYY-MM-DD + format: date + clientDisabledAt: + type: string + description: Дата отключения подписки клиентом в формате YYYY-MM-DD + format: date + extendedState: + type: string + description: "Расширенный статус подписки, для отображения экранов проло\ + нгации на обновленных версиях" + example: + nextFeeAt: 2000-01-23 + serviceCode: serviceCode + clientDisabledAt: 2000-01-23 + activatedAt: 2000-01-23T04:56:07.000+00:00 + extendedState: extendedState + state: state + disabledAt: 2000-01-23 + DeliveryPageResponse: + type: object + properties: + pagination: + $ref: '#/components/schemas/SimplePage' + items: + $ref: '#/components/schemas/DeliveryResponse' + example: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + items: + clientFio: Иванов И. И. + productionTypeCode: Неименная + documents: + - Паспорт + regionName: Москва + externalId: bf1d1b2f-9ebe-4bf1-8b8f-6f6f6f6f6f6f + viewCard: MIR Classic PW Ins + brokerageAccountRequired: false + smartRepeated: false + creationDate: 2025-01-01T00:00:00Z + courierFio: Иванов И. И. + productCode: CC + cityName: Москва + deliveryAddress: Ленина 45 + clientSES: false + slotTo: 12:00 + comment: Комментарий + processType: Детский банк. ИА Родитель + Ребёнок + deliveryDate: 2025-01-15T00:00:00Z + slotFrom: 10:00 + statusCode: В работе + DeliveryResponse: + type: object + properties: + externalId: + type: string + description: Cквозной код заявки внешних систем + example: bf1d1b2f-9ebe-4bf1-8b8f-6f6f6f6f6f6f + productCode: + type: string + description: Код продукта + example: CC + smartRepeated: + type: boolean + description: Признак умного повтора при заполнении заявки + example: false + productionTypeCode: + type: string + description: Тип производства карты + example: Неименная + creationDate: + type: string + description: Дата создания заявки + format: date-time + example: 2025-01-01T00:00:00Z + deliveryDate: + type: string + description: Дата доставки + format: date-time + example: 2025-01-15T00:00:00Z + slotFrom: + pattern: HH:mm + type: string + description: Начало слота доставки + example: 10:00 + slotTo: + pattern: HH:mm + type: string + description: Конец слота доставки + example: 12:00 + statusCode: + type: string + description: "Статус продукта в доставке, в зависимости от даты доставки\ + \ продукта сотрудником" + example: В работе + clientFio: + type: string + description: Фио клиента + example: Иванов И. И. + regionName: + type: string + description: Наименование региона + example: Москва + cityName: + type: string + description: Наименование города + example: Москва + deliveryAddress: + type: string + description: Адрес + example: Ленина 45 + courierFio: + type: string + description: Фио курьера + example: Иванов И. И. + viewCard: + type: string + description: Категория карты + example: MIR Classic PW Ins + clientSES: + type: boolean + description: Наличие простой электронной подписи клиента + example: false + comment: + type: string + description: Комментарий + example: Комментарий + brokerageAccountRequired: + type: boolean + description: Признак наличия брокерского счета + example: false + processType: + type: string + description: Название процесса + example: Детский банк. ИА Родитель + Ребёнок + documents: + type: array + description: Список документов + example: + - Паспорт + items: + type: string + description: Тип документа + description: Информация о доставке + example: + clientFio: Иванов И. И. + productionTypeCode: Неименная + documents: + - Паспорт + regionName: Москва + externalId: bf1d1b2f-9ebe-4bf1-8b8f-6f6f6f6f6f6f + viewCard: MIR Classic PW Ins + brokerageAccountRequired: false + smartRepeated: false + creationDate: 2025-01-01T00:00:00Z + courierFio: Иванов И. И. + productCode: CC + cityName: Москва + deliveryAddress: Ленина 45 + clientSES: false + slotTo: 12:00 + comment: Комментарий + processType: Детский банк. ИА Родитель + Ребёнок + deliveryDate: 2025-01-15T00:00:00Z + slotFrom: 10:00 + statusCode: В работе + OrderActionDto: + required: + - type + type: object + properties: + createdAt: + type: string + description: Дата и время перехода Заказа в описываемое состояние. ISO 8601. + format: date-time + type: + type: string + description: "Тип состояния заказа, соответствует action и определяет пе\ + редаваемый набор параметров" + enum: + - confirmed + - rejected + - deliver + - cancellinginprocess + - cancelled + - error + - atlastmile + - pickedup + - inprocess + - participantchanged + - providerchanged + - channelchanged + - renotified + - inprocesswarning + expireAt: + type: string + description: | + Дата-Время истечения максимального срока хранения Заказа на последнем логистическом плече. ISO 8601. + format: date-time + cancelledBy: + $ref: '#/components/schemas/OrderCancelledAllOfCancelledByDto' + reason: + type: string + description: | + Причина отмены или отклонения заказа + example: Невозможно принять заказ + cancelledAt: + type: string + description: | + Дата и время отмены заказа. ISO 8601. + format: date-time + channelId: + type: integer + description: | + Идентификатор канала + format: int64 + example: 1 + providerId: + type: integer + description: | + Идентификатор провайдера + format: int64 + example: 1 + confirmedAt: + type: string + description: | + Дата и время подтверждения заказа. ISO 8601. + format: date-time + tracking: + type: array + description: | + Массив объектов с информацией от провайдера для отслеживания заказа + items: + $ref: '#/components/schemas/TrackingDto' + providerStateDescription: + type: string + description: | + Человеко-читаемое описание текущего состояния на стороне провайдера + example: Заказ передан в сортировку + initiator: + $ref: '#/components/schemas/OrderCreatedAllOfInitiatorDto' + deliveredAt: + type: string + description: | + Дата и время доставки заказа. ISO 8601 + format: date-time + reportedBy: + $ref: '#/components/schemas/OrderErrorAllOfReportedByDto' + message: + type: string + description: | + Детализация ошибки + example: Заказ утерян + beginPointParticipant: + $ref: '#/components/schemas/ParticipantDto' + endPointParticipant: + $ref: '#/components/schemas/ParticipantDto' + rejectedBy: + $ref: '#/components/schemas/OrderRejectedAllOfRejectedByDto' + rejectedAt: + type: string + description: | + Дата и время отклонения заказа. ISO 8601 + format: date-time + channel: + $ref: '#/components/schemas/OrderStateDto_channel' + example: + reason: Невозможно принять заказ + providerStateDescription: Заказ передан в сортировку + cancelledAt: 2000-01-23T04:56:07.000+00:00 + initiator: + name: ПО Снабжение + beginPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + channel: + sms: "79999999999" + email: email@gmail.com + cancelledBy: + name: 5Post + type: provider + type: confirmed + expireAt: 2000-01-23T04:56:07.000+00:00 + reportedBy: + name: 5Post + type: system + message: Заказ утерян + tracking: + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + deliveredAt: 2000-01-23T04:56:07.000+00:00 + createdAt: 2000-01-23T04:56:07.000+00:00 + rejectedBy: + name: 5Post + type: provider + providerId: 1 + rejectedAt: 2000-01-23T04:56:07.000+00:00 + endPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + confirmedAt: 2000-01-23T04:56:07.000+00:00 + channelId: 1 + OrderCancelledAllOfCancelledByDto: + type: object + properties: + name: + type: string + description: | + Название субъекта, отменившего Заказ + example: 5Post + type: + type: string + description: | + Тип отменившего (провайдер, система и т.д.) + example: provider + description: | + Информация о том, кто отменил Заказ + example: + name: 5Post + type: provider + TrackingDto: + required: + - name + - value + type: object + properties: + name: + type: string + description: | + Название идентификатора отслеживания + example: Штрихкод + format: + type: string + description: | + Формат идентификатора + enum: + - BARCODE + - QR + - TRACKING_NUMBER + - LABEL + - CODE128 + value: + type: array + description: | + Значение идентификатора в формате base64 + example: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + items: + type: string + format: byte + example: + name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + OrderCreatedAllOfInitiatorDto: + type: object + properties: + name: + type: string + description: | + Название инициатора Заказа + example: ПО Снабжение + description: | + Информация об инициаторе создания Заказа + example: + name: ПО Снабжение + OrderErrorAllOfReportedByDto: + type: object + properties: + name: + type: string + description: | + Название источника ошибки + example: 5Post + type: + type: string + description: | + Тип источника ошибки (провайдер, система и т.д.) + example: system + description: | + Информация о том, кто сообщил об ошибке + example: + name: 5Post + type: system + ParticipantDto: + required: + - id + - name + - type + type: object + properties: + id: + type: integer + description: | + Идентификатор участника + format: int64 + readOnly: true + example: 35 + type: + type: string + description: | + Тип участника + example: SVK + enum: + - INDIVIDUAL + - SVK + - SPD + - LEGAL_ENTITY + name: + type: string + example: Иванов Иван Иванович + example: + name: Иванов Иван Иванович + id: 35 + type: SVK + OrderRejectedAllOfRejectedByDto: + type: object + properties: + name: + type: string + description: | + Название субъекта, отклонившего Заказ + example: 5Post + type: + type: string + description: | + Тип отклонившего (провайдер, система и т.д.) + example: provider + example: + name: 5Post + type: provider + OrderStateDto_channel: + type: object + properties: + sms: + type: string + description: "Номер телефона для SMS в международном формате (например,\ + \ +79999999999)" + example: "79999999999" + email: + type: string + description: Адрес электронной почты + format: email + example: email@gmail.com + description: | + Мапа, содержащая информацию о каналах для связи. + Доступные каналы: sms (номер телефона), email (адрес электронной почты). + example: + sms: "79999999999" + email: email@gmail.com + ErrorDto: + required: + - error + type: object + properties: + error: + type: string + description: | + Код ошибки + error_description: + type: string + description: | + Описание ошибки + ErrorScope_1: + required: + - error + type: object + properties: + error: + type: string + description: | + Код ошибки. Принимает возможные значения: + * 'insufficient_scope` - у пользователя нет прав на использование запрашиваемого сервиса, доступ к которому не предусмотрен настройками scope; + * `insufficient_privileges` - у пользователя нет прав на просмотр счёта; + * `access_denied` - доступ к счёту запрещён + example: insufficient_scope + error_description: + type: string + description: Описание ошибки + example: The request requires higher privileges than provided by the access + token + description: "У пользователя нет прав на использование запрашиваемого сервис\ + а, доступ к которому не предусмотрен настройками scope" + ProviderLocationDto: + required: + - address + - coordinates + - id + - name + - type + type: object + properties: + id: + type: string + description: | + Идентификатор локации в формате UUIDv7. + Если возвращается значение "00000000-0000-0000-0000-000000000000" - точка отправления не определена + readOnly: true + example: 019a150b-5a59-7883-8d22-79890fd909d6 + name: + type: string + description: Наименование локации + example: Постамат 5Post + type: + type: string + description: | + Тип локации + example: parcel_locker + enum: + - parcel_locker + - shop + address: + type: string + description: Полный адрес + example: "Москва г, ул Калинина, д 5" + coordinates: + $ref: '#/components/schemas/Coordinates' + description: + type: string + description: Описание постамата + example: Постамат на улице Калинина + externalId: + type: string + description: Идентификатор постамата на стороне провайдера + example: 019a150b-5a59-7883-8d22-79890fd909d6 + example: + address: "Москва г, ул Калинина, д 5" + name: Постамат 5Post + coordinates: + latitude: 0.8008281904610115 + longitude: 6.027456183070403 + description: Постамат на улице Калинина + externalId: 019a150b-5a59-7883-8d22-79890fd909d6 + id: 019a150b-5a59-7883-8d22-79890fd909d6 + type: parcel_locker + discriminator: + propertyName: type + Coordinates: + required: + - latitude + - longitude + type: object + properties: + latitude: + type: number + description: Широта + format: double + longitude: + type: number + description: Долгота + format: double + description: Объект с информацией о координатах адреса + example: + latitude: 0.8008281904610115 + longitude: 6.027456183070403 + LocationIds: + type: object + properties: + ids: + maxItems: 1000 + minItems: 1 + type: array + description: | + Массив идентификаторов локаций в формате UUIDv7 + items: + maxLength: 1000 + minLength: 1 + type: string + example: + ids: + - ids + - ids + - ids + - ids + - ids + OrderDto: + required: + - beginPoint + - endPoint + - parcel + type: object + properties: + id: + type: string + description: | + Идентификатор заказа + readOnly: true + providerId: + type: integer + format: int64 + readOnly: true + channelId: + type: integer + format: int64 + readOnly: true + limits: + $ref: '#/components/schemas/OrderLimitsDto' + parcel: + $ref: '#/components/schemas/ParcelDto' + beginPoint: + $ref: '#/components/schemas/LogisticPointDto' + endPoint: + $ref: '#/components/schemas/LogisticPointDto' + states: + type: array + description: | + Массив объектов с информацией о состояниях заказа + readOnly: true + items: + $ref: '#/components/schemas/OrderStateDto' + example: + endPoint: + phone: phone + locationId: locationId + from: 2000-01-23T04:56:07.000+00:00 + to: 2000-01-23T04:56:07.000+00:00 + participant: + name: Иванов Иван Иванович + id: 35 + type: SVK + email: email + parcel: + amount: 7 + length: 3 + width: 2 + externalIds: + key: externalIds + weight: 7 + description: description + value: 4 + height: 9 + beginPoint: + phone: phone + locationId: locationId + from: 2000-01-23T04:56:07.000+00:00 + to: 2000-01-23T04:56:07.000+00:00 + participant: + name: Иванов Иван Иванович + id: 35 + type: SVK + email: email + providerId: 0 + id: id + channelId: 6 + limits: + whiteListChannelIds: + - 1 + - 1 + blackListChannelIds: + - 5 + - 5 + whiteListProviderIds: + - 5 + - 5 + blackListProviderIds: + - 2 + - 2 + states: + - actual: false + reason: Невозможно принять заказ + providerStateDescription: Заказ передан в сортировку + cancelledAt: 2000-01-23T04:56:07.000+00:00 + initiator: + name: ПО Снабжение + beginPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + channel: + sms: "79999999999" + email: email@gmail.com + cancelledBy: + name: 5Post + type: provider + type: created + expireAt: 2000-01-23T04:56:07.000+00:00 + reportedBy: + name: 5Post + type: system + message: Заказ утерян + tracking: + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + deliveredAt: 2000-01-23T04:56:07.000+00:00 + createdAt: 2000-01-23T04:56:07.000+00:00 + rejectedBy: + name: 5Post + type: provider + providerId: 1 + rejectedAt: 2000-01-23T04:56:07.000+00:00 + endPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + confirmedAt: 2000-01-23T04:56:07.000+00:00 + channelId: 1 + - actual: false + reason: Невозможно принять заказ + providerStateDescription: Заказ передан в сортировку + cancelledAt: 2000-01-23T04:56:07.000+00:00 + initiator: + name: ПО Снабжение + beginPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + channel: + sms: "79999999999" + email: email@gmail.com + cancelledBy: + name: 5Post + type: provider + type: created + expireAt: 2000-01-23T04:56:07.000+00:00 + reportedBy: + name: 5Post + type: system + message: Заказ утерян + tracking: + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + deliveredAt: 2000-01-23T04:56:07.000+00:00 + createdAt: 2000-01-23T04:56:07.000+00:00 + rejectedBy: + name: 5Post + type: provider + providerId: 1 + rejectedAt: 2000-01-23T04:56:07.000+00:00 + endPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + confirmedAt: 2000-01-23T04:56:07.000+00:00 + channelId: 1 + OrderLimitsDto: + type: object + properties: + whiteListChannelIds: + type: array + description: | + Массив со списком идентификаторов каналов. + Заказ может быть обработан только через указанные каналы доставки. + items: + type: integer + format: int64 + blackListChannelIds: + type: array + description: | + Массив со списком идентификаторов каналов. + Запрещено использовать каналы доставки с переданными идентификаторами. + items: + type: integer + format: int64 + whiteListProviderIds: + type: array + description: | + Массив со списком идентификаторов провайдеров. + Заказ могут обслуживать только провайдеры, чьи идентификаторы были переданы. + items: + type: integer + format: int64 + blackListProviderIds: + type: array + description: | + Массив со списком идентификаторов провайдеров. + Запрещено назначать на заказ провайдеров с переданными идентификаторами. + items: + type: integer + format: int64 + description: | + Объект с информацией об ограничениях заказа на доставку. + Не учитывается провайдером, т.к. провайдер получает только доступные ему Заказы. + example: + whiteListChannelIds: + - 1 + - 1 + blackListChannelIds: + - 5 + - 5 + whiteListProviderIds: + - 5 + - 5 + blackListProviderIds: + - 2 + - 2 + ParcelDto: + required: + - description + - height + - length + - weight + - width + type: object + properties: + weight: + type: integer + description: | + Вес посылки в миллиграммах + format: int32 + height: + type: integer + description: | + Высота посылки в миллиметрах + format: int32 + length: + type: integer + description: | + Длина посылки в миллиметрах + format: int32 + width: + type: integer + description: | + Ширина посылки в миллиметрах + format: int32 + description: + type: string + description: | + Описание посылки + value: + type: integer + description: | + Объявленная ценность посылки + format: int32 + amount: + type: integer + description: | + Количество товаров в посылке + format: int32 + externalIds: + type: object + additionalProperties: + type: string + description: | + Внутри объекта находятся идентификаторы Заказа в Инициаторе заказа в формате ключ-значение (мапа) + description: | + Объект с информацией о доставляемой посылке + example: + amount: 7 + length: 3 + width: 2 + externalIds: + key: externalIds + weight: 7 + description: description + value: 4 + height: 9 + LogisticPointDto: + required: + - from + - locationId + - participant + - phone + - to + type: object + properties: + locationId: + type: string + description: | + Идентификатор локации в формате UUIDv7 + from: + type: string + description: | + Начало временного интервала (дата и время в формате ISO 8601) + format: date-time + to: + type: string + description: | + Конец временного интервала (дата и время в формате ISO 8601) + format: date-time + participant: + $ref: '#/components/schemas/ParticipantDto' + phone: + type: string + description: | + Номер телефона для связи с получателем/отправителем заказа + email: + type: string + description: | + Email-адрес для связи с получателем/отправителем заказа + example: + phone: phone + locationId: locationId + from: 2000-01-23T04:56:07.000+00:00 + to: 2000-01-23T04:56:07.000+00:00 + participant: + name: Иванов Иван Иванович + id: 35 + type: SVK + email: email + OrderStateDto: + required: + - actual + - type + type: object + properties: + createdAt: + type: string + description: Дата и время перехода Заказа в описываемое состояние. ISO 8601. + format: date-time + type: + type: string + description: "Тип состояния заказа, соответствует action и определяет пе\ + редаваемый набор параметров" + enum: + - created + - confirmed + - rejected + - delivered + - cancellinginprocess + - cancelled + - error + - atlastmile + - pickedup + - inprocess + - participantchanged + - providerchanged + - channelchanged + - renotified + - inprocesswarning + actual: + type: boolean + description: Признак актуальности состояния (true - текущее состояние) + example: false + expireAt: + type: string + description: | + Дата-Время истечения максимального срока хранения Заказа на последнем логистическом плече. ISO 8601. + format: date-time + cancelledBy: + $ref: '#/components/schemas/OrderCancelledAllOfCancelledByDto' + reason: + type: string + description: | + Причина отмены или отклонения заказа + example: Невозможно принять заказ + cancelledAt: + type: string + description: | + Дата и время отмены заказа. ISO 8601. + format: date-time + channelId: + type: integer + description: | + Идентификатор канала + format: int64 + example: 1 + providerId: + type: integer + description: | + Идентификатор провайдера + format: int64 + example: 1 + confirmedAt: + type: string + description: | + Дата и время подтверждения заказа. ISO 8601. + format: date-time + tracking: + type: array + description: | + Массив объектов с информацией от провайдера для отслеживания заказа + items: + $ref: '#/components/schemas/TrackingDto' + providerStateDescription: + type: string + description: | + Человеко-читаемое описание текущего состояния на стороне провайдера + example: Заказ передан в сортировку + initiator: + $ref: '#/components/schemas/OrderCreatedAllOfInitiatorDto' + deliveredAt: + type: string + description: | + Дата и время доставки заказа. ISO 8601 + format: date-time + reportedBy: + $ref: '#/components/schemas/OrderErrorAllOfReportedByDto' + message: + type: string + description: | + Детализация ошибки + example: Заказ утерян + beginPointParticipant: + $ref: '#/components/schemas/ParticipantDto' + endPointParticipant: + $ref: '#/components/schemas/ParticipantDto' + rejectedBy: + $ref: '#/components/schemas/OrderRejectedAllOfRejectedByDto' + rejectedAt: + type: string + description: | + Дата и время отклонения заказа. ISO 8601 + format: date-time + channel: + $ref: '#/components/schemas/OrderStateDto_channel' + example: + actual: false + reason: Невозможно принять заказ + providerStateDescription: Заказ передан в сортировку + cancelledAt: 2000-01-23T04:56:07.000+00:00 + initiator: + name: ПО Снабжение + beginPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + channel: + sms: "79999999999" + email: email@gmail.com + cancelledBy: + name: 5Post + type: provider + type: created + expireAt: 2000-01-23T04:56:07.000+00:00 + reportedBy: + name: 5Post + type: system + message: Заказ утерян + tracking: + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + - name: Штрихкод + format: BARCODE + value: + - 0J/RgNC40LLQtdGCLCDQvNC40YAg0LzRgtC30YHQtdC70Lg= + deliveredAt: 2000-01-23T04:56:07.000+00:00 + createdAt: 2000-01-23T04:56:07.000+00:00 + rejectedBy: + name: 5Post + type: provider + providerId: 1 + rejectedAt: 2000-01-23T04:56:07.000+00:00 + endPointParticipant: + name: Иванов Иван Иванович + id: 35 + type: SVK + confirmedAt: 2000-01-23T04:56:07.000+00:00 + channelId: 1 + ComplianceResponse: + required: + - result + type: object + properties: + result: + type: boolean + description: Результат проверки комплаенса + example: + result: true + requestUuid_1: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Идентификатор в формате UUID + example: 0521cc44-ae0f-4e73-9b16-a1630d50e444 + PaymentStatusResponse: + required: + - status + type: object + properties: + status: + type: string + description: | + Статус платежного поручения: * `NEW` - Новое; * `SENT` - Отправлено; * `ERROR` - Ошибка; * `RECEIVED` - Получено; * `VERIFICATION` - На проверке; * `REJECTED` - Отклонено; * `EXECUTION` - На исполнении; * `EXECUTED` - Исполнено; * `OVERDUE` - Просрочено; * `PARTIALLY_PAID` - Частично оплачено; * `PAID` - Оплачено; * `CLOSED` - Закрыто. + enum: + - NEW + - SENT + - ERROR + - RECEIVED + - VERIFICATION + - REJECTED + - EXECUTION + - EXECUTED + - OVERDUE + - PARTIALLY_PAID + - PAID + - CLOSED + description: Статус платежного поручения + example: + status: NEW + CreatePaymentRequest: + required: + - compensationPeriod + - creditorInfo + - currencyCode + - externalId + - monetaryClaimAmount + - orderType + - paymentPurpose + - principalInfo + type: object + properties: + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + description: Идентификатор в формате UUID + example: 0521cc44-ae0f-4e73-9b16-a1630d50e444 + principalInfo: + $ref: '#/components/schemas/PrincipalInfo' + creditorInfo: + $ref: '#/components/schemas/CreditorInfo' + orderType: + type: string + description: Тип платежного поручения + example: BUDGET + enum: + - BUDGET + - NONBUDGET + compensationPeriod: + type: string + description: Период компенсации (в днях) + example: "365" + paymentPurpose: + type: string + description: Назначение платежа + example: Оплата за услуги + currencyCode: + type: string + description: | + Код валюты: * `RUR` - Российский рубль; * `CNY` - Юань; * `UZS` - Узбекский сум; * `TRY` - Турецкая лира; * `KZT` - Тенге; * `TJS` - Сомони; * `KGS` - Сом; * `MDL` - Молдавский лей; * `JPY` - Йена; * `INR` - Индийская рупия; * `EUR` - Евро; * `USD` - Доллар США; * `AED` - Дирхам ОАЭ; * `BYN` - Белорусский рубль; * `AMD` - Армянский драм; * `AZN` - Азербайджанский манат. + example: RUB + enum: + - RUR + - CNY + - UZS + - TRY + - KZT + - TJS + - KGS + - MDL + - JPY + - INR + - EUR + - USD + - AED + - BYN + - AMD + - AZN + monetaryClaimAmount: + type: number + description: Сумма поручения (денежного требования) + example: 150077.88 + monetaryClaimId: + type: string + description: Идентификатор денежного требования (опционально) + example: claim-123 + contractNumber: + type: string + description: Номер контракта (опционально) + example: "12345" + contractDate: + type: string + description: Дата контракта (опционально) + format: date + example: 2023-05-10 + fixedRatePercentage: + type: number + description: Фиксированная ставка (% годовых) (опционально) + example: 5.5 + floatRatePercentage: + type: number + description: Надбавка плавающей ставки (% пунктов) (опционально) + example: 1.25 + paymentPriority: + type: string + description: Очередность платежа (опционально) + example: "5" + payerStatus: + type: string + description: Статус плательщика (опционально) + example: "101" + accrualUniqueId: + type: string + description: "Уникальный идентификатор начисления, УИН (опционально)" + example: 22-1234567890 + taxPaymentCode: + type: string + description: Код основания налогового платежа (опционально) + example: "106" + taxPeriod: + type: string + description: Налоговый период (опционально) + example: "2021" + baseDocumentType: + type: string + description: Документ-основание (опционально) + example: Счет + baseDocumentDate: + type: string + description: Дата документа-основания (опционально) + example: 2023-04-01 + kbk: + type: string + description: КБК кредитора (опционально) + example: "18210102010011000110" + oktmo: + type: string + description: ОКТМО кредитора (опционально) + example: "45384000" + description: Запрос на сохранение платежного поручения + example: + orderType: BUDGET + monetaryClaimId: claim-123 + contractDate: 2023-05-10T00:00:00.000+00:00 + compensationPeriod: "365" + taxPeriod: "2021" + monetaryClaimAmount: 150077.88 + floatRatePercentage: 1.25 + externalId: 0521cc44-ae0f-4e73-9b16-a1630d50e444 + contractNumber: "12345" + fixedRatePercentage: 5.5 + creditorInfo: + ogrn: "1027700132195" + name: ООО Кредитор + inn: "7707083893" + bankBIC: "044525225" + bankCorrAccountNumber: "30101810400000000225" + kpp: "773601001" + bankName: Банк Пример + accountNumber: "40702810500000000001" + principalInfo: + name: ООО Виктория + inn: "7707083893" + kpp: "773601001" + paymentPriority: "5" + payerStatus: "101" + accrualUniqueId: 22-1234567890 + baseDocumentType: Счет + taxPaymentCode: "106" + oktmo: "45384000" + kbk: "18210102010011000110" + paymentPurpose: Оплата за услуги + baseDocumentDate: 2023-04-01 + currencyCode: RUB + PrincipalInfo: + required: + - inn + - name + type: object + properties: + name: + type: string + description: Наименование принципала + example: ООО Виктория + inn: + type: string + description: ИНН принципала + example: "7707083893" + kpp: + type: string + description: КПП принципала (опционально) + example: "773601001" + description: Данные принципала + example: + name: ООО Виктория + inn: "7707083893" + kpp: "773601001" + CreditorInfo: + required: + - accountNumber + - bankBIC + - bankCorrAccountNumber + - bankName + - inn + - name + type: object + properties: + name: + type: string + description: Наименование кредитора + example: ООО Кредитор + inn: + type: string + description: ИНН кредитора + example: "7707083893" + kpp: + type: string + description: КПП кредитора (опционально) + example: "773601001" + ogrn: + type: string + description: ОГРН кредитора (опционально) + example: "1027700132195" + bankName: + type: string + description: Наименование банка кредитора + example: Банк Пример + bankBIC: + type: string + description: БИК банка кредитора + example: "044525225" + bankCorrAccountNumber: + type: string + description: Корреспондентский счет банка кредитора + example: "30101810400000000225" + accountNumber: + type: string + description: Расчетный счет кредитора + example: "40702810500000000001" + description: Данные кредитора + example: + ogrn: "1027700132195" + name: ООО Кредитор + inn: "7707083893" + bankBIC: "044525225" + bankCorrAccountNumber: "30101810400000000225" + kpp: "773601001" + bankName: Банк Пример + accountNumber: "40702810500000000001" + SavePaymentResponse: + required: + - externalId + - paymentId + type: object + properties: + externalId: + type: string + description: Идентификатор платежного поручения в ERP системе + format: uuid + example: f47ac10b-58cc-4372-a567-0e02b2c3d479 + paymentId: + type: string + description: Идентификатор платежного поручения в банке + format: uuid + description: Ответ при сохранении платежного поручения + example: + paymentId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + externalId: f47ac10b-58cc-4372-a567-0e02b2c3d479 + RegisterStatusResponse: + required: + - status + type: object + properties: + status: + type: string + description: | + Статус реестра: * `NEW` - Новое; * `SENT` - Отправлено; * `ERROR` - Ошибка; * `RECEIVED` - Загружено; * `VERIFICATION` - На проверке; * `EXECUTION` - В работе; * `EXECUTED` - Исполнено; * `OVERDUE` - Просрочено; * `PAID` - Оплачено; * `REJECTED` - Отклонено; * `CLOSED` - Закрыто. + enum: + - NEW + - SENT + - ERROR + - RECEIVED + - VERIFICATION + - EXECUTION + - EXECUTED + - OVERDUE + - PAID + - REJECTED + - CLOSED + description: Статус реестра платежных поручений + example: + status: NEW + CreateRegisterRequest: + required: + - paymentIds + - plannedExecutionDate + - totalSum + type: object + properties: + totalSum: + type: number + description: Общая сумма по всем платежным поручениям + example: 100000.01 + plannedExecutionDate: + type: string + description: "Плановая дата исполнения поручения, заполняется при создан\ + ии реестра поручений" + format: date + example: 2024-02-15 + paymentIds: + maxItems: 1000 + minItems: 1 + type: array + description: массив уникальных идентификаторов платежных поручений + items: + $ref: '#/components/schemas/requestUuid_1' + description: Данные для создания и обработки платежных поручений + example: + totalSum: 100000.01 + paymentIds: + - 0521cc44-ae0f-4e73-9b16-a1630d50e444 + - 0521cc44-ae0f-4e73-9b16-a1630d50e444 + - 0521cc44-ae0f-4e73-9b16-a1630d50e444 + - 0521cc44-ae0f-4e73-9b16-a1630d50e444 + - 0521cc44-ae0f-4e73-9b16-a1630d50e444 + plannedExecutionDate: 2024-02-15T00:00:00.000+00:00 + SaveRegisterResponse: + required: + - file + - id + type: object + properties: + id: + type: string + description: Идентификатор реестра + format: uuid + example: 76ec6909-dacd-47af-a71d-9db02a3679a7 + file: + type: string + description: Base64-кодированный файл + example: SGVsbG8sIFdvcmxkIQ== + registerNumber: + type: integer + description: Номер реестра + format: int32 + example: 13791 + description: Ответ при сохранении реестра платежных поручений + example: + file: SGVsbG8sIFdvcmxkIQ== + id: 76ec6909-dacd-47af-a71d-9db02a3679a7 + registerNumber: 13791 + SignRegisterRequest: + required: + - digestSignatures + - registerId + type: object + properties: + registerId: + type: string + description: Идентификатор реестра + format: uuid + digestSignatures: + $ref: '#/components/schemas/DigestSignatures_3' + description: Запрос на подписание реестра платежных поручений + example: + digestSignatures: + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + registerId: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + DigestSignatures_3: + required: + - base64Encoded + - certificateUuid + type: object + properties: + base64Encoded: + type: string + description: Подпись принципала в формате Base64 + example: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: + type: string + description: Идентификатор сертификата + format: uuid + example: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + description: Данные подписи принципала + example: + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + SignRegisterResponse: + type: object + properties: + message: + type: string + description: Успешное подписание реестра + example: + message: message + UpdateOrderRequest: + required: + - orderId + - status + type: object + properties: + quantity: + type: integer + description: Количество лимитов списание которых отменяем по данному orderId + (extnum) + format: int64 + example: 5 + orderId: + type: string + description: Внешний уникальный идентификатор операции снятия лимитов + example: ST1057RQKDD + partnerName: + type: string + description: Название организации-партнера которая запрашивает списание + example: ST + status: + type: string + description: Новый статус заказа + example: L + example: + quantity: 5 + orderId: ST1057RQKDD + partnerName: ST + status: L + UpdateOrderResponse: + type: object + properties: + quantity: + type: integer + description: Количество оставшихся действующих списаний по данному extnum + (внешний orderId) + format: int64 + orderId: + type: string + description: Внешний референс запроса + partnerName: + type: string + description: Название организации-партнера которая запрашивает редактирование + status: + type: string + description: Новый статус заказа + example: + quantity: 0 + orderId: orderId + partnerName: partnerName + status: status + CreateOrderRequest: + required: + - quantity + type: object + properties: + quantity: + type: integer + description: Кол-во лимитов к списанию + format: int64 + example: 4 + partnerName: + type: string + description: Название организации-партнера которая запрашивает списание + example: ST + createdAt: + type: string + description: Дата создания заказа на списание + format: date-time + example: 2024-01-11T23:19:09.224Z + example: + createdAt: 2024-01-11T23:19:09.224Z + quantity: 4 + partnerName: ST + CreateOrderResponse: + type: object + properties: + quantity: + type: integer + description: Количество лимитов снятых по запросу + format: int64 + orderId: + type: string + description: Внешний референс запроса + partnerName: + type: string + description: Название организации-партнера которая запрашивает списание + createdAt: + type: string + description: Дата создания заказа на списание + format: date-time + example: + createdAt: 2000-01-23T04:56:07.000+00:00 + quantity: 0 + orderId: orderId + partnerName: partnerName + ErrorLowBalance: + required: + - error + type: object + properties: + error: + type: string + description: Код ошибки + example: operation_refused + error_description: + type: string + example: "Unable to process: low balance" + description: Недостаточно кол-во лимитов для осуществления компенсации + GetBalanceResponse: + type: object + properties: + quantity: + type: integer + description: Баланс лимитов БЗ + format: int64 + customerSP: + type: string + description: Пакет услуг клиента + example: + quantity: 0 + customerSP: customerSP + CreateLoungeReportRequest: + type: object + properties: + id: + type: string + description: Уникальный идентификатор события в системе партнера + format: uuid + alfaData: + $ref: '#/components/schemas/AlfaDataDto' + count: + $ref: '#/components/schemas/CountDto' + category: + type: string + description: Тип услуги + enum: + - BUSINESS_LOUNGE + - VIP_LOUNGE + - FAST_TRACK + usingArea: + type: string + description: Регион услуги + enum: + - DOMESTIC + - INTERNATIONAL + - ALFA + requestDateTime: + type: string + description: Дата и время создания услуги (utc 0) + format: date-time + eventDateTime: + type: string + description: Дата и время создания события услуги (utc 0) + format: date-time + service: + $ref: '#/components/schemas/ServiceDto' + price: + $ref: '#/components/schemas/PriceDto' + transactionType: + type: string + description: Тип оформления услуги + enum: + - FREE + - PAID + eventStatus: + type: string + description: Тип события по услуге + enum: + - CREATED + - EXECUTED + - CANCELLED + - TRANSPORT_HUB_CANCELLED + - EXPIRED + - PAID + example: + transactionType: FREE + eventDateTime: 2000-01-23T04:56:07.000+00:00 + requestDateTime: 2000-01-23T04:56:07.000+00:00 + service: + country: country + travelType: DOMESTIC + transportHub: transportHub + name: name + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + type: ARRIVAL + price: + total: 5.637376656633329 + baby: 9.301444243932576 + adult: 2.3021358869347655 + child: 7.061401241503109 + eventStatus: CREATED + alfaData: + orderId: orderId + userId: userId + count: + request: 0 + baby: 5 + adult: 6 + child: 1 + usingArea: DOMESTIC + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + category: BUSINESS_LOUNGE + AlfaDataDto: + type: object + properties: + userId: + type: string + description: Внешний идентификатор клиента банка (ФЛ) + orderId: + type: string + description: Внешний номер заказа + format: "uuid," + example: + orderId: orderId + userId: userId + CountDto: + type: object + properties: + request: + type: integer + description: Кол-во гостей в запросе на услугу + format: int32 + adult: + type: integer + description: Кол-во взрослых в событии услуги + format: int32 + child: + type: integer + description: Кол-во детей в событии услуги + format: int32 + baby: + type: integer + description: Кол-во младенцев в событии услуги + format: int32 + example: + request: 0 + baby: 5 + adult: 6 + child: 1 + ServiceDto: + type: object + properties: + id: + type: string + description: Id услуги + format: uuid + name: + type: string + description: Название услуги + transportHub: + type: string + description: Название аэропорта + country: + type: string + description: Название страны + type: + type: string + description: Тип услуги + enum: + - ARRIVAL + - DEPARTURE + - GENERAL + travelType: + type: string + description: Тип поездки + enum: + - DOMESTIC + - INTERNATIONAL + - GENERAL + example: + country: country + travelType: DOMESTIC + transportHub: transportHub + name: name + id: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + type: ARRIVAL + PriceDto: + type: object + properties: + total: + type: number + description: Итоговая стоимость с учетом кол-ва гостей + adult: + type: number + description: Стоимость за 1 взрослого + child: + type: number + description: Стоимость за 1 ребенка + baby: + type: number + description: Стоимость за 1 младенца + example: + total: 5.637376656633329 + baby: 9.301444243932576 + adult: 2.3021358869347655 + child: 7.061401241503109 + LoungeReportResponse: + type: object + properties: + createdId: + type: string + description: Идентификатор созданного ресурса + example: + createdId: createdId + getInitialPlacementListResponse: + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_3' + items: + $ref: '#/components/schemas/DFAInitial' + description: Ответ метода + example: + pagination: + offset: 10 + limit: 10 + totalCount: 100 + items: + statusDate: 2023-08-03T14:17:51.525Z + dfaExtraInfoList: 1 ЦФА = 1 кв.м + dfaHybridAssetAddress: г. Москва + dfaStartDate: 2023-02-01T00:00:00Z + companyIssuerName: АО Вольт + companyIssuerEmail: volt@mail.ru + dfaSecondaryStartDate: 2023-08-03T14:17:51.525Z + dfaParValue: 100000 + dfaBorrowerOgrn: "6131238182674" + dfaId: BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaDebtPaymentPeriodComment: комментарий + dfaMinNumber: 1 + dfaBankAccount: "47422810800000000038" + dfaMinValue: 1000000 + dfaHardcapEnd: 15 + dfaRestrictionValue: 44650800 + dfaName: ALFB-1-SB-082023-00001 + subtitle: Структурная облигация + dfaMinSellPrice: 50000 + dfaHybridPaymentDeadline: В рублях в течение 3-х рабочих дней с момента + направления Эмитенту Заявки на погашение ЦФА + placementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + status: PRESALE + dfaDocConditionsKey: /dfa/docs/74450795-de9d-40ee-895f-1945c53886fb + dfaSecondaryQualificationPersonRequirements: QUALIFIED_ONLY + dfaPriceStep: 100 + dfaRedemptionDate: 2027-08-18T00:00:00.000+00:00 + icon: https://testdfa.alfabank.ru:9010/dfa/icons/750ad7ea-3158-4966-afab-643ae3f8cd7f + dfaDocIconName: sample.jpg + contractVersion: 53 + buyPlacementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/buy?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaLoanStartDate: 2023-08-03T14:17:51.525Z + dfaPrettyName: Лабиринт + dfaDocPresentationKey: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + dfaProductVariety: Цифровые обязательства + dfaSubType: Структурная облигация + companyIssuerInn: "0514564365" + dfaQualificationCompanyRequirements: ALL + dfaIssuerFee: 3.0 + dfaSaleEndDate: 2023-08-03T14:17:51.525Z + dfaMaxBuyPrice: 1000000 + dfaMaxValue: 1000000 + dfaDocPresentationName: Презентация.pdf + availableOnSecondaryMarket: true + dfaLoanEndDate: 2023-08-03T14:17:51.525Z + dfaTotalAmount: 10000 + dfaType: MONEY_CLAIM + companyIssuerOgrn: "1130731080666" + dfaMaxNumber: 7 + dfaBorrowerName: Иванов Иван Иванович + dfaMaxRate: 15.3 + dfaDocIconKey: /dfa/icons/d82ffa63-bda0-4e56-92e7-522829a721ba + dfaHybridAssetDeadline: В течение 10 рабочих дней с момента направления + Эмитенту Заявки на погашение ЦФА + dfaDocs: + - preferences: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + files: + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + order: 1 + - preferences: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + files: + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + order: 1 + dfaNpdPaymentPeriodComment: комментарий + dfaLoanAmount: Отсутствует + dfaDebtAccrualPeriodComment: комментарий + dfaAvailableForIssuer: true + redemptionRule: BY_AMORTIZATION + dfaRateRangeEnable: true + dfaMaxSellPrice: 500000 + dfaEndDate: 2023-02-01T00:00:00Z + dfaRestriction: true + companyIssuerAddress: "Октябрьская улица 123, д.18" + creationDate: 2023-08-03T14:17:51.525Z + placementOneLink: https://testdfa.alfabank.ru/mobile/goto/dfa_webview_with_two_parameters?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaSecondaryQualificationCompanyRequirements: QUALIFIED_ONLY + companyIssuerSite: volt.ru + dfaDebtPaymentPeriod: EOP + dfaDebtAccrualPeriod: EOP + background: '#36363A' + dfaHybridSelectedTypes: + - "[\"CASH\"]" + - "[\"CASH\"]" + dfaLifeTime: "10000" + dfaLoanRate: 10.6 + dfaDocConditionsName: Презентация.pdf + companyIssuerId: 8rJg73mcacMn5p6Fmpsre1Jk3rwU4yz7UzDpFfGyShH4 + dfaSecondarySellerFee: 1.3 + exchangeContractVersion: 54 + dfaReleaseDecisionKey: docs/5f5537b4-d633-4c1b-8e9f-4d3406162246 + description: Участие от 10 000Р + title: АЛЬФА-БАНК + dfaLoanNumber: "654321" + profitOnDfa: 0 + tokensaleHardcap: true + dfaInvestorFee: 1.1 + dfaNpdAccrualPeriodComment: комментарий + dfaMinRate: 5.7 + dfaBorrowerInn: "369930244602" + dfaRateAmount: "13.2" + buyPlacementOneLink: https://test-alfa-mobile.alfabank.ru/mobile/goto/dfa_id_buy_dc?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaMinBuyPrice: 100000 + dfaLoanRateType: FIXED + dfaReleaseDecisionName: Презентация.pdf + refAsset: + blocks: + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + name: Структурная облигация + dfaQualificationPersonRequirements: ALL + dfaNpdAccrualPeriod: EOP + dfaRateType: FIXED + dfaSecondaryBuyerFee: 1.2 + dfaCurrency: RUB + dfaNpdPaymentPeriod: EOP + Pagination_3: + type: object + properties: + offset: + type: number + description: "Количество объектов в списке, которые необходимо пропустит\ + ь" + example: 10 + limit: + type: number + description: Количество объектов на одной странице + example: 10 + totalCount: + type: number + description: Общее количество записей + example: 100 + description: Пагинация + example: + offset: 10 + limit: 10 + totalCount: 100 + DFAInitial: + required: + - background + - buyPlacementLink + - buyPlacementOneLink + - companyIssuerAddress + - companyIssuerEmail + - companyIssuerId + - companyIssuerInn + - companyIssuerName + - companyIssuerOgrn + - companyIssuerSite + - creationDate + - description + - dfaBankAccount + - dfaCurrency + - dfaDebtAccrualPeriod + - dfaDebtPaymentPeriod + - dfaDocConditionsKey + - dfaDocConditionsName + - dfaDocIconKey + - dfaDocIconName + - dfaDocPresentationKey + - dfaDocPresentationName + - dfaEndDate + - dfaId + - dfaIssuerFee + - dfaMaxNumber + - dfaMinNumber + - dfaName + - dfaParValue + - dfaProductVariety + - dfaSaleEndDate + - dfaStartDate + - dfaTotalAmount + - dfaType + - icon + - placementLink + - placementOneLink + - redemptionRule + - status + - statusDate + - subtitle + - title + - tokensaleHardcap + type: object + properties: + title: + type: string + description: Заголовок размещения + example: АЛЬФА-БАНК + subtitle: + type: string + description: Подзаголовок + example: Структурная облигация + description: + type: string + description: Описание + example: Участие от 10 000Р + icon: + type: string + description: Ссылка на изображение иконки + format: url + example: https://testdfa.alfabank.ru:9010/dfa/icons/750ad7ea-3158-4966-afab-643ae3f8cd7f + background: + type: string + description: Цвет фона + example: '#36363A' + placementLink: + type: string + description: Прямая ссылка на карточку размещения + format: url + example: https://testdfa.alfabank.ru/retail-investor/webview/dfa/BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + buyPlacementLink: + type: string + description: Прямая ссылка на покупку размещения + format: url + example: https://testdfa.alfabank.ru/retail-investor/webview/dfa/buy?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + buyPlacementOneLink: + type: string + description: Ссылка редиректа на покупку размещения через АМ/АО + format: url + example: https://test-alfa-mobile.alfabank.ru/mobile/goto/dfa_id_buy_dc?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + placementOneLink: + type: string + description: Ссылка редиректа на размещения через АМ/АО + format: url + example: https://testdfa.alfabank.ru/mobile/goto/dfa_webview_with_two_parameters?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaId: + type: string + description: Уникальный идентификатор ЦФА + example: BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaName: + type: string + description: Наименование ЦФА + example: ALFB-1-SB-082023-00001 + dfaType: + type: string + description: | + Тип ЦФА. Принимает возможные значения: + * `MONEY_CLAIM` - денежное требование; + * `HYBRID_ASSET` - гибридный актив; + * `MONEY_CLAIM_CREDIT` - денежное требование по кредитному договору + example: MONEY_CLAIM + enum: + - MONEY_CLAIM + - HYBRID_ASSET + - MONEY_CLAIM_CREDIT + dfaQualificationPersonRequirements: + type: string + description: | + Требования к квалификации инвестора ФЛ. Принимает возможные значения: + * `ALL` - все; + * `QUALIFIED_ONLY` - квалифицированный инвестор; + * `UNQUALIFIED_LIMIT` - доступно для неквалифицированных инвесторов с ограничением по сумме + example: ALL + enum: + - ALL + - QUALIFIED_ONLY + - UNQUALIFIED_LIMIT + dfaQualificationCompanyRequirements: + type: string + description: | + Требования к квалификации инвестора ЮЛ. Принимает возможные значения: + * `ALL` - все; + * `QUALIFIED_ONLY` - квалифицированный инвестор; + * `UNQUALIFIED_LIMIT` - доступно для неквалифицированных инвесторов с ограничением по сумме + example: ALL + enum: + - ALL + - QUALIFIED_ONLY + - UNQUALIFIED_LIMIT + dfaBankAccount: + type: string + description: Номер счёта эмитента + example: "47422810800000000038" + companyIssuerId: + type: string + description: Уникальный идентификатор эмитента + example: 8rJg73mcacMn5p6Fmpsre1Jk3rwU4yz7UzDpFfGyShH4 + companyIssuerName: + type: string + description: Полное наименование эмитента + example: АО Вольт + companyIssuerOgrn: + type: string + description: ОГРН эмитента + example: "1130731080666" + companyIssuerAddress: + type: string + description: Юридический адрес эмитента + example: "Октябрьская улица 123, д.18" + companyIssuerEmail: + type: string + description: Email эмитента + format: email + example: volt@mail.ru + companyIssuerSite: + type: string + description: Сайт эмитента + example: volt.ru + companyIssuerInn: + type: string + description: ИНН эмитента + example: "0514564365" + dfaParValue: + type: integer + description: Цена одного ЦФА в минорных единицах + format: int64 + example: 100000 + dfaCurrency: + type: string + description: | + Валюта ЦФА. Принимает возможные значения: + * `EUR` - евро; + * `USD` - американский доллар; + * `RUB` - российский рубль + example: RUB + dfaRestriction: + type: boolean + description: Ограничение объема выпуска в денежном выражении + example: true + dfaRestrictionValue: + type: integer + description: Сумма ограничения выпуска + format: int64 + example: 44650800 + dfaRateType: + type: string + description: | + Тип процентной ставки. Принимает возможные значения: + * `FIXED` - фиксированная; + * `FLOAT` - переменная; + * `BARRIER` - барьерная; + * `NONE` - отсутствует + example: FIXED + dfaRateAmount: + type: string + description: Размер фиксированной процентной ставки (%) или информация о + базовом активе + example: "13.2" + dfaNpdPaymentPeriod: + type: string + description: | + Периодичность выплаты НПД. Принимает возможные значения: + * `D` - ежедневно; + * `M` - ежемесячно; + * `Y` - ежегодно; + * `Q` - ежеквартально; + * `EOP` - в конце срока; + * `None` - отсутствует; + * `O` - другое + example: EOP + enum: + - D + - M + - "Y" + - Q + - EOP + - NONE + - O + dfaNpdPaymentPeriodComment: + type: string + description: Комментарий к периодичности выплат НПД + example: комментарий + dfaNpdAccrualPeriod: + type: string + description: | + Периодичность начисления НПД. Принимает возможные значения: + * `D` - ежедневно; + * `M` - ежемесячно; + * `Y` - ежегодно; + * `Q` - ежеквартально; + * `EOP` - в конце срока; + * `None` - отсутствует; + * `O` - другое + example: EOP + enum: + - D + - M + - "Y" + - Q + - EOP + - NONE + - O + dfaNpdAccrualPeriodComment: + type: string + description: Комментарий к периодичности начислений НПД + example: комментарий + dfaDebtAccrualPeriod: + type: string + description: | + Периодичность начисления основного долга. Принимает возможные значения: + * `D` - ежедневно; + * `M` - ежемесячно; + * `Y` - ежегодно; + * `Q` - ежеквартально; + * `EOP` - в конце срока; + * `None` - отсутствует; + * `O` - другое + example: EOP + enum: + - D + - M + - "Y" + - Q + - EOP + - NONE + - O + dfaDebtAccrualPeriodComment: + type: string + description: Комментарий к периодичности начислений ОД + example: комментарий + dfaDebtPaymentPeriod: + type: string + description: | + Периодичность выплаты основного долга. Принимает возможные значения: + * `D` - ежедневно; + * `M` - ежемесячно; + * `Y` - ежегодно; + * `Q` - ежеквартально; + * `EOP` - в конце срока; + * `None` - отсутствует; + * `O` - другое + example: EOP + enum: + - D + - M + - "Y" + - Q + - EOP + - NONE + - O + dfaDebtPaymentPeriodComment: + type: string + description: Комментарий к периодичности выплат ОД + example: комментарий + dfaRedemptionDate: + type: string + description: Дата погашения ЦФА + format: date + example: 2027-08-18 + status: + type: string + description: | + Статус смарт-контракта. Принимает возможные значения: + * `PRESALE` - размещение/сбор заявок + example: PRESALE + statusDate: + type: string + description: Дата изменения статуса + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaMinValue: + type: integer + description: Минимальный объём выпуска ЦФА в валюте выпуска (минорные единицы) + format: int64 + example: 1000000 + dfaMaxValue: + type: integer + description: Максимальный объём выпуска ЦФА в валюте выпуска (минорные единицы) + format: int64 + example: 1000000 + dfaMinNumber: + type: integer + description: Минимальный объём выпуска ЦФА в штуках + format: int64 + example: 1 + dfaMaxNumber: + type: integer + description: Максимальный объём выпуска ЦФА в штуках + format: int64 + example: 7 + dfaRateRangeEnable: + type: boolean + description: Принимать предложения о процентной ставке от инвесторов + example: true + dfaMinRate: + type: number + description: "Минимальная ставка, %" + format: double + example: 5.7 + dfaMaxRate: + type: number + description: "Максимальная ставка, %" + format: double + example: 15.3 + dfaStartDate: + type: string + description: Дата начала первичного размещения + format: date-time + example: 2023-02-01T00:00:00Z + dfaEndDate: + type: string + description: Дата начала окончания размещения + format: date-time + example: 2023-02-01T00:00:00Z + dfaSaleEndDate: + type: string + description: Дата закрытия книги предварительных заявок + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaDocIconName: + type: string + description: Наименование иконки + example: sample.jpg + deprecated: true + dfaDocIconKey: + type: string + description: Иконка. *Рекомендуемое использование:* Используйте ссылку из + поля icon + example: /dfa/icons/d82ffa63-bda0-4e56-92e7-522829a721ba + deprecated: true + dfaDocConditionsName: + type: string + description: Условия первичного размещения. Имя файла + example: Презентация.pdf + dfaDocConditionsKey: + type: string + description: Условия первичного размещения. Ключ в MinIO + example: /dfa/docs/74450795-de9d-40ee-895f-1945c53886fb + dfaDocPresentationKey: + type: string + description: Прямая ссылка на документ презентации. *Рекомендуемое использование:* + Используйте ссылку из массива dfaDocs.files.url вместо данной + example: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + deprecated: true + dfaDocPresentationName: + type: string + description: Презентация. Наименование документа + example: Презентация.pdf + deprecated: true + dfaReleaseDecisionKey: + type: string + description: Итоговое решение о выпуске. Ключ в MinIO + example: docs/5f5537b4-d633-4c1b-8e9f-4d3406162246 + deprecated: true + dfaReleaseDecisionName: + type: string + description: Итоговое решение о выпуске. Наименование документа + example: Презентация.pdf + deprecated: true + dfaInvestorFee: + type: number + description: "Комиссия инвестора на первичном рынке, %" + format: double + example: 1.1 + dfaSecondaryBuyerFee: + type: number + description: "Комиссия покупателя на вторичном рынке, %" + format: double + example: 1.2 + dfaSecondarySellerFee: + type: number + description: "Комиссия продавца на вторичном рынке, %" + format: double + example: 1.3 + tokensaleHardcap: + type: boolean + description: Признак достигнутого завершения сбора заявок на это размещение + example: true + availableOnSecondaryMarket: + type: boolean + description: Доступность ЦФА на вторичном рынке + example: true + dfaPriceStep: + type: integer + description: Шаг цены для ЦФА на вторичном рынке. Указывается в минорных + единицах (копейках) + format: int64 + example: 100 + dfaBorrowerName: + type: string + description: Наименование заёмщика + example: Иванов Иван Иванович + dfaBorrowerInn: + type: string + description: ИНН заёмщика + example: "369930244602" + dfaBorrowerOgrn: + type: string + description: ОГРН заёмщика + example: "6131238182674" + dfaLoanNumber: + type: string + description: Номер кредитного договора + example: "654321" + dfaLoanAmount: + type: string + description: Задолженность по КД + example: Отсутствует + dfaLoanRateType: + type: string + description: Тип процентной ставки. + example: FIXED + dfaLoanRate: + type: number + description: "Значение ставки, %" + format: double + example: 10.6 + dfaLoanStartDate: + type: string + description: Дата начала срока действия КД + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaLoanEndDate: + type: string + description: Дата окончания срока действия КД + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaMinBuyPrice: + type: integer + description: Минимальная цена покупки + format: int64 + example: 100000 + dfaMaxBuyPrice: + type: integer + description: Максимальная цена покупки + format: int64 + example: 1000000 + dfaMinSellPrice: + type: integer + description: Минимальная цена продажи + format: int64 + example: 50000 + dfaMaxSellPrice: + type: integer + description: Максимальная цена продажи + format: int64 + example: 500000 + profitOnDfa: + type: integer + description: Доход на ЦФА + format: int64 + contractVersion: + type: integer + description: Версия контракта + format: int64 + example: 53 + exchangeContractVersion: + type: integer + description: Изменение версии контракта + format: int64 + example: 54 + creationDate: + type: string + description: Дата создания записи + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaTotalAmount: + type: integer + description: "Фактическое количество ЦФА, приобретенное инвесторами в вы\ + пуске" + format: int64 + example: 10000 + dfaIssuerFee: + type: number + description: "Комиссия оператора для эмитента, %" + format: double + example: 3.0 + dfaHybridSelectedTypes: + type: array + items: + type: string + description: | + Выбранные типы погашения ЦФА. Принимает возможные значения: + * `CASH` - в виде денежных средств; + * `ASSET` - в виде передачи физического актива + example: "[\"CASH\"]" + dfaHybridPaymentDeadline: + type: string + description: Срок перечисления денежных средств + example: В рублях в течение 3-х рабочих дней с момента направления Эмитенту + Заявки на погашение ЦФА + dfaHybridAssetDeadline: + type: string + description: Срок получения гибридного актива + example: В течение 10 рабочих дней с момента направления Эмитенту Заявки + на погашение ЦФА + dfaHybridAssetAddress: + type: string + description: Адрес получения гибридного актива + example: г. Москва + dfaSecondaryQualificationPersonRequirements: + type: string + description: | + Требования к квалификации инвестора ФЛ на вторичном рынке. Принимает возможные значения: + * `ALL` - все; + * `QUALIFIED_ONLY` - квалифицированный инвестор; + * `UNQUALIFIED_LIMIT` - доступно для неквалифицированных инвесторов с ограничением по сумме + example: QUALIFIED_ONLY + enum: + - ALL + - QUALIFIED_ONLY + - UNQUALIFIED_LIMIT + dfaSecondaryQualificationCompanyRequirements: + type: string + description: | + Требования к квалификации инвестора ЮЛ на вторичном рынке. Принимает возможные значения: + * `ALL` - все; + * `QUALIFIED_ONLY` - квалифицированный инвестор; + * `UNQUALIFIED_LIMIT` - доступно для неквалифицированных инвесторов с ограничением по сумме + example: QUALIFIED_ONLY + enum: + - ALL + - QUALIFIED_ONLY + - UNQUALIFIED_LIMIT + dfaHardcapEnd: + type: integer + description: Остаток до хардкапа + format: int64 + example: 15 + dfaSecondaryStartDate: + type: string + description: Дата выхода ЦФА на вторичный рынок + format: date-time + example: 2023-08-03T14:17:51.525Z + dfaAvailableForIssuer: + type: boolean + description: Флаг доступности вторичного рынка для эмитента + example: true + redemptionRule: + type: string + description: | + Условие погашения ЦФА. Принимает возможные значения: + * `BY_LAST_ACCRUAL` - по факту исполнения последнего начисления ОД по графику без учета амортизации ЦФА; + * `BY_AMORTIZATION` - по факту исполнения очередного начисления ОД по графику при котором амортизационная стоимость ЦФА стала равна 0 + example: BY_AMORTIZATION + enum: + - BY_LAST_ACCRUAL + - BY_AMORTIZATION + dfaProductVariety: + type: string + description: Наименование типа продукта для покупателя + example: Цифровые обязательства + dfaSubType: + type: string + description: Подтип ЦФА + example: Структурная облигация + dfaPrettyName: + type: string + description: Маркетинговое наименование ЦФА + example: Лабиринт + dfaExtraInfoList: + type: string + description: "Доп инфа по цфа. В зависимсоти от размещения может отображ\ + аться процентная ставка, КС +0,5%, 1 ЦФА = 1 кв.м, 1 ЦФА = 0.1 карат" + example: 1 ЦФА = 1 кв.м + dfaLifeTime: + type: string + description: Время жизни ЦФА + example: "10000" + refAsset: + $ref: '#/components/schemas/refAsset' + dfaDocs: + type: array + description: Массив групп документов по эмиссии (кроме изображения ЦФА) + items: + $ref: '#/components/schemas/DFADoc' + description: Массив объектов результата + example: + statusDate: 2023-08-03T14:17:51.525Z + dfaExtraInfoList: 1 ЦФА = 1 кв.м + dfaHybridAssetAddress: г. Москва + dfaStartDate: 2023-02-01T00:00:00Z + companyIssuerName: АО Вольт + companyIssuerEmail: volt@mail.ru + dfaSecondaryStartDate: 2023-08-03T14:17:51.525Z + dfaParValue: 100000 + dfaBorrowerOgrn: "6131238182674" + dfaId: BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaDebtPaymentPeriodComment: комментарий + dfaMinNumber: 1 + dfaBankAccount: "47422810800000000038" + dfaMinValue: 1000000 + dfaHardcapEnd: 15 + dfaRestrictionValue: 44650800 + dfaName: ALFB-1-SB-082023-00001 + subtitle: Структурная облигация + dfaMinSellPrice: 50000 + dfaHybridPaymentDeadline: В рублях в течение 3-х рабочих дней с момента направления + Эмитенту Заявки на погашение ЦФА + placementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + status: PRESALE + dfaDocConditionsKey: /dfa/docs/74450795-de9d-40ee-895f-1945c53886fb + dfaSecondaryQualificationPersonRequirements: QUALIFIED_ONLY + dfaPriceStep: 100 + dfaRedemptionDate: 2027-08-18T00:00:00.000+00:00 + icon: https://testdfa.alfabank.ru:9010/dfa/icons/750ad7ea-3158-4966-afab-643ae3f8cd7f + dfaDocIconName: sample.jpg + contractVersion: 53 + buyPlacementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/buy?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaLoanStartDate: 2023-08-03T14:17:51.525Z + dfaPrettyName: Лабиринт + dfaDocPresentationKey: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + dfaProductVariety: Цифровые обязательства + dfaSubType: Структурная облигация + companyIssuerInn: "0514564365" + dfaQualificationCompanyRequirements: ALL + dfaIssuerFee: 3.0 + dfaSaleEndDate: 2023-08-03T14:17:51.525Z + dfaMaxBuyPrice: 1000000 + dfaMaxValue: 1000000 + dfaDocPresentationName: Презентация.pdf + availableOnSecondaryMarket: true + dfaLoanEndDate: 2023-08-03T14:17:51.525Z + dfaTotalAmount: 10000 + dfaType: MONEY_CLAIM + companyIssuerOgrn: "1130731080666" + dfaMaxNumber: 7 + dfaBorrowerName: Иванов Иван Иванович + dfaMaxRate: 15.3 + dfaDocIconKey: /dfa/icons/d82ffa63-bda0-4e56-92e7-522829a721ba + dfaHybridAssetDeadline: В течение 10 рабочих дней с момента направления Эмитенту + Заявки на погашение ЦФА + dfaDocs: + - preferences: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + files: + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + order: 1 + - preferences: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + files: + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + order: 1 + dfaNpdPaymentPeriodComment: комментарий + dfaLoanAmount: Отсутствует + dfaDebtAccrualPeriodComment: комментарий + dfaAvailableForIssuer: true + redemptionRule: BY_AMORTIZATION + dfaRateRangeEnable: true + dfaMaxSellPrice: 500000 + dfaEndDate: 2023-02-01T00:00:00Z + dfaRestriction: true + companyIssuerAddress: "Октябрьская улица 123, д.18" + creationDate: 2023-08-03T14:17:51.525Z + placementOneLink: https://testdfa.alfabank.ru/mobile/goto/dfa_webview_with_two_parameters?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaSecondaryQualificationCompanyRequirements: QUALIFIED_ONLY + companyIssuerSite: volt.ru + dfaDebtPaymentPeriod: EOP + dfaDebtAccrualPeriod: EOP + background: '#36363A' + dfaHybridSelectedTypes: + - "[\"CASH\"]" + - "[\"CASH\"]" + dfaLifeTime: "10000" + dfaLoanRate: 10.6 + dfaDocConditionsName: Презентация.pdf + companyIssuerId: 8rJg73mcacMn5p6Fmpsre1Jk3rwU4yz7UzDpFfGyShH4 + dfaSecondarySellerFee: 1.3 + exchangeContractVersion: 54 + dfaReleaseDecisionKey: docs/5f5537b4-d633-4c1b-8e9f-4d3406162246 + description: Участие от 10 000Р + title: АЛЬФА-БАНК + dfaLoanNumber: "654321" + profitOnDfa: 0 + tokensaleHardcap: true + dfaInvestorFee: 1.1 + dfaNpdAccrualPeriodComment: комментарий + dfaMinRate: 5.7 + dfaBorrowerInn: "369930244602" + dfaRateAmount: "13.2" + buyPlacementOneLink: https://test-alfa-mobile.alfabank.ru/mobile/goto/dfa_id_buy_dc?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaMinBuyPrice: 100000 + dfaLoanRateType: FIXED + dfaReleaseDecisionName: Презентация.pdf + refAsset: + blocks: + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + name: Структурная облигация + dfaQualificationPersonRequirements: ALL + dfaNpdAccrualPeriod: EOP + dfaRateType: FIXED + dfaSecondaryBuyerFee: 1.2 + dfaCurrency: RUB + dfaNpdPaymentPeriod: EOP + refAsset: + required: + - name + type: object + properties: + name: + type: string + description: Наименование актива + example: Структурная облигация + blocks: + type: array + description: Массив блоков актива + items: + $ref: '#/components/schemas/refAssetBlock' + description: Объект с данными об активе + example: + blocks: + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + name: Структурная облигация + refAssetBlock: + required: + - isRequired + - name + - parameters + - visibility + type: object + properties: + name: + type: string + description: Наименование блока + example: external + isRequired: + type: boolean + description: Флаг обязательности блока + example: true + visibility: + type: array + example: COMPANY + items: + type: string + description: | + Кому блок отображается в карточке. Принимает возможные значения: + * `ALL` - Все; + * `NOBODY` - никто; + * `COMPANY` - юридическое лицо; + * `PERSON` - физическое лицо + parameters: + type: array + description: Массив параметров блока + items: + $ref: '#/components/schemas/refAssetBlockParam' + description: Блок с данными об активе + example: + isRequired: true + visibility: COMPANY + name: external + parameters: + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + - isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + refAssetBlockParam: + required: + - isRequired + - name + - value + - visibility + type: object + properties: + name: + type: string + description: Наименование параметра + example: title + value: + type: string + description: Значение параметра + example: "1,7% (20,4% годовых)" + isRequired: + type: boolean + description: Флаг обязательности + example: false + visibility: + type: array + example: COMPANY + items: + type: string + description: | + Кому блок отображается в карточке. Принимает возможные значения: + * `ALL` - все; + * `NOBODY` - никто; + * `COMPANY` - юридическое лицо; + * `PERSON` - физическое лицо + description: Параметры блока + example: + isRequired: false + visibility: COMPANY + name: title + value: "1,7% (20,4% годовых)" + DFADoc: + type: object + properties: + order: + type: number + description: "Порядок блока документов, заданный при создании решения" + example: 1 + preferences: + $ref: '#/components/schemas/DFADocPreferences' + files: + type: array + description: Массив документов (файлов) в группе. Может содержать до 10 + items: + $ref: '#/components/schemas/DFADocFile' + description: Документ по эмиссии + example: + preferences: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + files: + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + - name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + order: 1 + DFADocPreferences: + required: + - formats + - id + - isRequired + - name + - visibility + type: object + properties: + id: + type: string + description: Идентификатор типа документов + example: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + name: + type: string + description: Название типа документов + example: Презентация + isRequired: + type: boolean + description: Обязательность типа документов + example: false + visibility: + type: array + example: COMPANY + items: + type: string + description: | + Доступность документа для отображения в карточке ЦФА по типам инвесторов. Принимает возможные значения: + * `ISSUER` - эмитент ЦФА; + * `PERSON` - физическое лицо; + * `COMPANY` - юридическое лицо; + * Пустой массив + formats: + type: array + example: PDF + items: + type: string + description: | + Типы файлов, доступные для документа. Принимает возможные значения: + * `PDF` - PDF-файл; + * `PNG` - PNG-файл + description: + type: string + description: Описание типа документа + example: Презентация выпуска + singleFile: + type: boolean + description: "Признак, что файл может быть только 1 в группе" + example: false + noDuplicates: + type: boolean + description: "Признак, что группа не может дублироваться в рамках ЦФА" + example: false + description: Объект с атрибутами группы документа + example: + noDuplicates: false + isRequired: false + formats: PDF + visibility: COMPANY + name: Презентация + description: Презентация выпуска + singleFile: false + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + DFADocFile: + required: + - key + - name + - url + type: object + properties: + id: + type: string + description: "id файла, сгенерированного при загрузке " + example: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + name: + type: string + description: Наименование документа + example: Презентация.pdf + url: + type: string + description: Прямая ссылка для получения документа + example: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: + type: string + description: Ключ в MinIO + example: docs/55ac2445-19fc-44d5-94c8-764a827764ba + description: Объект с атрибутами группы документа + example: + name: Презентация.pdf + id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + ResponseCertificates: + type: array + description: Ответ на запрос получения всех сертификатов + items: + $ref: '#/components/schemas/ResponseCertificates_inner' + RequestAddCertificate: + type: object + properties: + type: + type: string + example: ENCRYPTION + enum: + - ENCRYPTION + - SIGNATURE + - TLS + certificateBody: + type: string + example: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + description: Запрос на добавление сертификата + example: + type: ENCRYPTION + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + ResponseCertificate: + required: + - algorithm + - beginDateTime + - certificateBody + - clientId + - expireDateTime + - fingerprint + - id + - ownerName + - serialNumber + - status + - type + type: object + properties: + id: + type: string + example: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + clientId: + type: string + example: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + ownerName: + type: string + example: Иванов Иван Иванович + fingerprint: + type: string + example: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + organizationName: + type: string + nullable: true + example: ООО 'Рога и Копыта' + beginDateTime: + type: string + format: date-time + example: 2023-07-28T15:11:14Z + expireDateTime: + type: string + format: date-time + example: 2025-06-19T11:48:06Z + status: + type: string + example: ACTIVE + enum: + - ACTIVE + - REVOKED + - DELETED + certificateBody: + type: string + example: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: + type: string + example: ENCRYPTION + enum: + - ENCRYPTION + - SIGNATURE + - TLS + algorithm: + type: string + example: RS256 + enum: + - RS256 + - GOST + serialNumber: + type: string + example: "2163173489423972678179275487230070851350268586" + description: Ответ на запрос получения / добавления / обновления статуса сертификата + example: + expireDateTime: 2025-06-19T11:48:06Z + clientId: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + serialNumber: "2163173489423972678179275487230070851350268586" + ownerName: Иванов Иван Иванович + organizationName: ООО 'Рога и Копыта' + fingerprint: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + id: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + beginDateTime: 2023-07-28T15:11:14Z + type: ENCRYPTION + status: ACTIVE + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + algorithm: RS256 + RequestChangeCertificate: + required: + - op + - path + - value + type: object + properties: + op: + type: string + example: replace + enum: + - replace + path: + type: string + example: /status + enum: + - /status + value: + type: string + example: REVOKED + enum: + - ACTIVE + - REVOKED + description: Запрос обновления статуса сертификата + example: + op: replace + path: /status + value: REVOKED + claims-resolved: + title: Обработанные на стороне Партнера обращения + required: + - employeeReply + - resolution + - resolutionDate + type: object + properties: + resolution: + type: string + description: | + Решение по обращению + - POSITIVE - Позитивное решение + - NEGATIVE - Негативное решение + - WITHIN_BANK_COMPETENCE - Решение в компетенции Банка + enum: + - POSITIVE + - NEGATIVE + - WITHIN_BANK_COMPETENCE + orderId: + maxLength: 36 + type: string + description: Номер заказа партнера + resolutionDate: + type: string + description: Дата и время решения обращения на стороне Партнера (UTC+3) + format: date-time + clientReply: + maxLength: 4000 + type: string + description: "Ответ для клиента, если необходимо" + nullable: true + employeeReply: + maxLength: 4000 + type: string + description: Ответ для сотрудника + PostOrderTravel: + required: + - content + - dateTime + - externalId + - totalSum + - type + type: object + properties: + externalId: + type: string + description: Идентификатор заказа в системе партнера + example: "3248901" + accountType: + type: string + description: Тип бонусного счета для оплаты + example: Мили + ruleId: + type: integer + description: Идентификатор типа правила + example: 12 + type: + $ref: '#/components/schemas/Type' + dateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + totalSum: + type: number + description: Общая сумма заказа в рублях + example: 254.1 + bonusPayment: + maxItems: 3 + type: array + description: Массив с объектами оплаты бонусной частью + items: + $ref: '#/components/schemas/BonusPaymentItems' + cashPayment: + maxItems: 30 + type: array + description: Массив с объектами оплаты денежной частью + items: + $ref: '#/components/schemas/CashPaymentItems' + content: + $ref: '#/components/schemas/ContentTravel' + reportData: + $ref: '#/components/schemas/ReportData' + description: Тело запроса для создания заказа партнерами из бизнес линии Travel + ExternalId: + type: string + description: Идентификатор заказа в системе партнера + example: "3248901" + AccountType_2: + type: string + description: Тип бонусного счета для оплаты + example: Мили + RuleId: + type: integer + description: Идентификатор типа правила + example: 12 + Type: + type: string + description: Тип заказа * `AVIA` - Авиа заказ; * `RAILWAY` - ЖД заказ; * `HOTEL` + - Отель; * `TOUR` - Заказ тура; + example: AVIA + enum: + - AVIA + - RAILWAY + - HOTEL + - TOUR + DateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + TotalSum: + type: number + description: Общая сумма заказа в рублях + example: 254.1 + BonusPayment: + maxItems: 3 + type: array + description: Массив с объектами оплаты бонусной частью + items: + $ref: '#/components/schemas/BonusPaymentItems' + BonusPaymentItems: + required: + - sum + - sumRubEquivalent + - type + type: object + properties: + type: + $ref: '#/components/schemas/BonusType' + sumRubEquivalent: + type: number + description: Сумма оплаты бонусными единицами в рублевом эквиваленте + example: 1000 + sum: + type: number + description: Сумма оплаты + example: 500 + comment: + type: string + description: Комментарий к оплате бонусной частью + nullable: true + example: Оплачиваю часть милями + description: Объект с данными бонусной части оплаты заказа + BonusType: + type: integer + description: | + Тип бонусной операции: + - **0** — Оплата основного заказа + - **1** — Фиксированная ставка + - **2** — Процент от суммы + - **3** — Комиссия третьих лиц + format: int32 + example: 0 + enum: + - 0 + - 1 + - 2 + - 3 + SumRubEquivalent: + type: number + description: Сумма оплаты бонусными единицами в рублевом эквиваленте + example: 1000 + Sum: + type: number + description: Сумма оплаты + example: 500 + Comment: + type: string + description: Комментарий к оплате бонусной частью + nullable: true + example: Оплачиваю часть милями + CashPayment: + maxItems: 30 + type: array + description: Массив с объектами оплаты денежной частью + items: + $ref: '#/components/schemas/CashPaymentItems' + CashPaymentItems: + required: + - currency + - sum + - type + type: object + properties: + type: + type: string + description: Тип оплаты рублями + example: Оплата комиссии в пользу 3-их лиц + sum: + type: number + description: Сумма оплаты + example: 500 + currency: + maxLength: 3 + type: string + description: Валюта оплаты + example: RUB + additionalProperties: false + description: Объект с данными денежной части оплаты заказа + CashType: + type: string + description: Тип оплаты рублями + example: Оплата комиссии в пользу 3-их лиц + Currency_2: + maxLength: 3 + type: string + description: Валюта оплаты + example: RUB + ContentTravel: + required: + - reservationSource + - travelers + type: object + properties: + utilizationDate: + type: string + description: Дата утилизации тура + format: date-time + example: 2023-10-05T14:30:00Z + reservationSource: + $ref: '#/components/schemas/ReservationSource' + additionalServices: + maxItems: 50 + type: array + description: Массив с объектами доп.услуг + items: + $ref: '#/components/schemas/AdditionalServicesItems' + tripType: + $ref: '#/components/schemas/TripType' + segments: + maxItems: 50 + type: array + description: Массив с сегментами перелета/жд переезда + items: + $ref: '#/components/schemas/SegmentsTravelItems' + hotel: + $ref: '#/components/schemas/Hotel' + tour: + $ref: '#/components/schemas/Tour' + travelers: + $ref: '#/components/schemas/Travelers' + additionalProperties: false + description: | + Содержимое заказа для партнеров бизнес линии "Travel". + Поддерживаемые типы заказов: + - AVIA - авиабилеты + - RAILWAY - железнодорожные билеты + - HOTEL - бронирование отелей + - TOUR - пакетные туры + UtilizationDate: + type: string + description: Дата утилизации тура + format: date-time + example: 2023-10-05T14:30:00Z + ReservationSource: + type: string + description: Источник бронирования * `WEBVIEW` - вебвью; * `SITE` - сайт; + example: WEBVIEW + enum: + - WEBVIEW + - SITE + AdditionalServices: + maxItems: 50 + type: array + description: Массив с объектами доп.услуг + items: + $ref: '#/components/schemas/AdditionalServicesItems' + AdditionalServicesItems: + required: + - currency + - name + - sum + - type + type: object + properties: + name: + type: string + description: Наименование доп.услуги + example: Выбор места + type: + type: string + description: Тип доп.услуги + example: place_choice + sum: + type: number + description: Сумма оплаты + example: 500 + currency: + maxLength: 3 + type: string + description: Валюта оплаты + example: RUB + additionalProperties: false + description: Содержимое доп.услуги + Name: + type: string + description: Наименование доп.услуги + example: Выбор места + AdditionalServiceType: + type: string + description: Тип доп.услуги + example: place_choice + TripType: + type: string + description: Тип путешествия * `OW` - в одну сторону; * `RT` - туда обратно; + * `CX` - сложный маршрут; + example: OW + enum: + - OW + - RT + - CX + SegmentsTravel: + maxItems: 50 + type: array + description: Массив с сегментами перелета/жд переезда + items: + $ref: '#/components/schemas/SegmentsTravelItems' + SegmentsTravelItems: + required: + - arrival + - departure + - type + type: object + properties: + class: + type: string + description: Класс билета + example: A + type: + type: string + description: Тип рейса/тип поезда + example: REGULAR + sequence: + type: integer + description: Последовательность + example: 1 + number: + type: string + description: Номер рейса/поезда + example: P-06-28921 + supplier: + type: string + description: Название перевозчика + example: Ural Airlines + direction: + type: string + description: Направление + example: "0" + departure: + $ref: '#/components/schemas/Departure' + arrival: + $ref: '#/components/schemas/Arrival' + luggage: + maxItems: 50 + type: array + description: Массив с информацией о багаже + items: + $ref: '#/components/schemas/LuggageItems' + additionalProperties: false + description: Содержимое перелета или жд переезда + Class: + type: string + description: Класс билета + example: A + SegmentType: + type: string + description: Тип рейса/тип поезда + example: REGULAR + Sequence: + type: integer + description: Последовательность + example: 1 + SegmentNumber: + type: string + description: Номер рейса/поезда + example: P-06-28921 + Supplier: + type: string + description: Название перевозчика + example: Ural Airlines + Direction: + type: string + description: Направление + example: "0" + Departure: + required: + - city + - country + - point + type: object + properties: + dateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + city: + type: string + description: Код города отправления/прибытия + example: MOW + country: + type: string + description: Код страны отправления/прибытия + example: RUS + point: + type: string + description: Код аэропорта/вокзала отправления/прибытия + example: VKO + additionalProperties: false + description: Объект с содержимым деталей вылета + City_1: + type: string + description: Код города отправления/прибытия + example: MOW + Country_1: + type: string + description: Код страны отправления/прибытия + example: RUS + Point: + type: string + description: Код аэропорта/вокзала отправления/прибытия + example: VKO + Arrival: + required: + - city + - country + - point + type: object + properties: + dateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + city: + type: string + description: Код города отправления/прибытия + example: MOW + country: + type: string + description: Код страны отправления/прибытия + example: RUS + point: + type: string + description: Код аэропорта/вокзала отправления/прибытия + example: VKO + additionalProperties: false + description: Объект с содержимым деталей прилета + Luggage: + maxItems: 50 + type: array + description: Массив с информацией о багаже + items: + $ref: '#/components/schemas/LuggageItems' + LuggageItems: + required: + - amount + - type + - weight + type: object + properties: + type: + type: string + description: Тип багажа + example: Wheeled Duffel Bags + amount: + type: integer + description: Количество багажа + example: 5 + weight: + type: number + description: Вес багажа + example: 10 + width: + type: number + description: Ширина багажа + example: 10 + length: + type: number + description: Длина багажа + example: 5 + height: + type: number + description: Высота багажа + example: 5 + additionalProperties: false + description: Содержимое багажа + LuggageType: + type: string + description: Тип багажа + example: Wheeled Duffel Bags + Amount_2: + type: integer + description: Количество багажа + example: 5 + Weight: + type: number + description: Вес багажа + example: 10 + Width: + type: number + description: Ширина багажа + example: 10 + Length: + type: number + description: Длина багажа + example: 5 + Height: + type: number + description: Высота багажа + example: 5 + Hotel: + required: + - checkInDate + - checkOutDate + - city + - country + - name + - roomType + type: object + properties: + name: + type: string + description: Наименование отеля + example: Горный пик + roomType: + type: string + description: Тип комнаты + example: Номер эконом с 1 двуспальной кроватью + checkInDate: + type: string + description: Дата заезда + format: date-time + example: 2020-10-12T12:00:00Z + checkOutDate: + type: string + description: Дата выезда + format: date-time + example: 2020-10-14T15:00:00Z + city: + type: string + description: Код города отеля + example: MOW + country: + type: string + description: Код города страны отеля + example: RUS + stars: + type: integer + description: Количество звезд отеля + example: 4 + mealType: + type: string + description: Тип питания + example: halfBoardDinner + additionalProperties: false + description: Содержимое заказа отеля + HotelName: + type: string + description: Наименование отеля + example: Горный пик + RoomType: + type: string + description: Тип комнаты + example: Номер эконом с 1 двуспальной кроватью + CheckInDate: + type: string + description: Дата заезда + format: date-time + example: 2020-10-12T12:00:00Z + CheckOutDate: + type: string + description: Дата выезда + format: date-time + example: 2020-10-14T15:00:00Z + HotelCity: + type: string + description: Код города отеля + example: MOW + HotelCountry: + type: string + description: Код города страны отеля + example: RUS + Stars: + type: integer + description: Количество звезд отеля + example: 4 + MealType: + type: string + description: Тип питания + example: halfBoardDinner + Tour: + required: + - operator + type: object + properties: + operator: + type: string + description: Оператор тура + example: SpaceTravel + provider: + type: string + description: Провайдер тура + example: Travel + additionalProperties: false + description: Объект с содержимым данныых о заказе тура + Operator: + type: string + description: Оператор тура + example: SpaceTravel + Provider: + type: string + description: Провайдер тура + example: Travel + Travelers: + required: + - adults + - children + - infants + type: object + properties: + adults: + type: integer + description: Количество взрослых + example: 2 + children: + type: integer + description: Количество детей + example: 1 + infants: + type: integer + description: Количество младенцев + example: 1 + additionalProperties: false + description: Объект с данными о путешественниках + Adults: + type: integer + description: Количество взрослых + example: 2 + Children: + type: integer + description: Количество детей + example: 1 + Infants: + type: integer + description: Количество младенцев + example: 1 + ReportData: + type: object + properties: + bookingType: + type: string + description: Тип бронирования + example: GDS + startPrice: + type: number + description: Цена нетто + example: 255.55 + markup: + type: number + description: Маркап + example: 255.96 + aviakassaFee: + type: number + description: Комиссия авиакассы + example: 100000 + supplierFee: + type: number + description: Комиссия поставщика + example: 555657 + gdsBonus: + type: number + description: Комиссия GDS + example: 1000 + comissionFee: + type: number + description: Комиссионное вознаграждение + example: 5898 + passengers: + maxItems: 50 + type: array + description: Массив с билетами и идентификаторами пассажиров + items: + $ref: '#/components/schemas/PassengersItems' + flights: + maxItems: 50 + type: array + description: Массив с данными для аналитики по перелету + items: + $ref: '#/components/schemas/FlightsItems' + additionalProperties: true + description: Объект с данными для аналитики + BookingType: + type: string + description: Тип бронирования + example: GDS + StartPrice: + type: number + description: Цена нетто + example: 255.55 + Markup: + type: number + description: Маркап + example: 255.96 + AviakassaFee: + type: number + description: Комиссия авиакассы + example: 100000 + SupplierFee: + type: number + description: Комиссия поставщика + example: 555657 + GdsBonus: + type: number + description: Комиссия GDS + example: 1000 + ComissionFee: + type: number + description: Комиссионное вознаграждение + example: 5898 + Passengers: + maxItems: 50 + type: array + description: Массив с билетами и идентификаторами пассажиров + items: + $ref: '#/components/schemas/PassengersItems' + PassengersItems: + type: object + properties: + id: + type: integer + description: Идентификатор пассажира + example: 756 + ticketNumber: + type: string + description: номер билета + example: E584 + additionalProperties: true + description: Объект с билетами и идентификаторами пассажиров + PassengerId: + type: integer + description: Идентификатор пассажира + example: 756 + TicketNumber: + type: string + description: номер билета + example: E584 + Flights: + maxItems: 50 + type: array + description: Массив с данными для аналитики по перелету + items: + $ref: '#/components/schemas/FlightsItems' + FlightsItems: + type: object + properties: + flightNumber: + type: string + description: номер рейса + example: ST006 + locator: + type: string + description: локатор + example: 26W4GS + additionalProperties: true + description: Объект с с данными для аналитики по перелету + FlightNumber: + type: string + description: номер рейса + example: ST006 + Locator: + type: string + description: локатор + example: 26W4GS + SuccessResponseCreateOrder: + type: object + properties: + orderId: + maxLength: 50 + type: string + description: Идентификатор заказа в банке + example: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: + maxLength: 50 + type: string + description: Статус созданного заказа + example: Created + OrderId: + maxLength: 50 + type: string + description: Идентификатор заказа в банке + example: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + StatusCreate: + maxLength: 50 + type: string + description: Статус созданного заказа + example: Created + SuccessResponseAlreadyOrder: + type: object + properties: + orderId: + maxLength: 50 + type: string + description: Идентификатор заказа в банке + example: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: + maxLength: 50 + type: string + description: Статус созданного заказа + example: Order already exists + example: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Order already exists + Status_1: + maxLength: 50 + type: string + description: Статус созданного заказа + example: Order already exists + ErrorBadGateway: + type: object + properties: + error: + type: string + description: Ошибка + example: bad_gateway + error_description: + type: string + description: Описание ошибки + example: Can't hold miles + description: Ошибка с сообщением + BadGatewayError: + type: string + description: Ошибка + example: bad_gateway + BadGatewayDescription: + type: string + description: Описание ошибки + example: Can't hold miles + PostOrderAfisha: + required: + - content + - dateTime + - externalId + - totalSum + - type + type: object + properties: + externalId: + type: string + description: Идентификатор заказа в системе партнера + example: "3248901" + accountType: + type: string + description: Тип бонусного счета для оплаты + example: Мили + ruleId: + type: integer + description: Идентификатор типа правила + example: 12 + type: + $ref: '#/components/schemas/AfishaType' + dateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + totalSum: + type: number + description: Общая сумма заказа в рублях + example: 254.1 + bonusPayment: + maxItems: 3 + type: array + description: Массив с объектами оплаты бонусной частью + items: + $ref: '#/components/schemas/BonusPaymentItems' + cashPayment: + maxItems: 30 + type: array + description: Массив с объектами оплаты денежной частью + items: + $ref: '#/components/schemas/CashPaymentItems' + content: + $ref: '#/components/schemas/AfishaContent' + description: Тело запроса для создания заказа партнерами из бизнес линии Afisha + AfishaType: + type: string + description: Тип заказа * `EVENT` - Мероприятие; + example: EVENT + enum: + - EVENT + AfishaContent: + required: + - address + - city + - country + - date + - eventId + - eventName + - venue + type: object + properties: + eventName: + type: string + description: Наименование мероприятия + example: Концерт A Studio + eventId: + type: string + description: Идентификатор мероприятия в системе партнера + example: AST_P_007 + venue: + type: string + description: Название площадки мероприятия + example: Зеленый театр + country: + type: string + description: Код страны мероприятия/доставки покупки + example: RUS + city: + type: string + description: Код города мероприятия/доставки покупки + example: MOW + date: + type: string + description: Дата и время мероприятия/доставки покупки + format: date-time + example: 2029-10-05T14:30:00Z + address: + type: string + description: Адрес мероприятия/доставки покупки + example: "Г.Москва, 123134, улица Народного Ополчения" + tickets: + maxItems: 100 + type: array + description: Массив с билетами + items: + $ref: '#/components/schemas/TicketsItems' + description: Объект c типом заказа event + EventName: + type: string + description: Наименование мероприятия + example: Концерт A Studio + EventId: + type: string + description: Идентификатор мероприятия в системе партнера + example: AST_P_007 + Venue: + type: string + description: Название площадки мероприятия + example: Зеленый театр + PurchaseCountry: + type: string + description: Код страны мероприятия/доставки покупки + example: RUS + PurchaseCity: + type: string + description: Код города мероприятия/доставки покупки + example: MOW + PurchaseDate: + type: string + description: Дата и время мероприятия/доставки покупки + format: date-time + example: 2029-10-05T14:30:00Z + Address_3: + type: string + description: Адрес мероприятия/доставки покупки + example: "Г.Москва, 123134, улица Народного Ополчения" + Tickets: + maxItems: 100 + type: array + description: Массив с билетами + items: + $ref: '#/components/schemas/TicketsItems' + TicketsItems: + type: object + properties: + seat: + type: string + description: Место + example: "32" + row: + type: string + description: Ряд + example: "10" + sector: + type: string + description: Сектор + example: B8 + description: Состав объекта с билетами + Seat: + type: string + description: Место + example: "32" + Row: + type: string + description: Ряд + example: "10" + Sector: + type: string + description: Сектор + example: B8 + PutOrderTravel: + required: + - changeReason + - content + - dateTime + - externalId + - totalSum + - type + type: object + properties: + externalId: + type: string + description: Идентификатор заказа в системе партнера + example: "3248901" + type: + $ref: '#/components/schemas/Type' + dateTime: + type: string + description: Дата + format: date-time + example: 2023-10-05T14:30:00Z + totalSum: + type: number + description: Общая сумма заказа в рублях + example: 254.1 + ruleId: + type: integer + description: Идентификатор типа правила + example: 12 + changeReason: + $ref: '#/components/schemas/ChangeReason' + transaction: + maxItems: 20 + type: array + description: Массив с транзакциями + items: + $ref: '#/components/schemas/TransactionItems' + accountType: + type: string + description: Тип бонусного счета для оплаты + example: Мили + bonusPayment: + maxItems: 3 + type: array + description: Массив с объектами оплаты бонусной частью + items: + $ref: '#/components/schemas/BonusPaymentItems' + cashPayment: + maxItems: 30 + type: array + description: Массив с объектами оплаты денежной частью + items: + $ref: '#/components/schemas/CashPaymentItems' + content: + $ref: '#/components/schemas/ContentTravel' + reportData: + $ref: '#/components/schemas/ReportData' + description: Тело запроса для обновления заказа партнерами из бизнес линии Travel + ChangeReason: + type: string + description: Причина изменения в заказе * `ADDITIONAL_SERVICES` - доп.услуги; + * `EXCHANGE` - обмен; * `CHANGE_TIMETABLE` - изменение расписания; * `PARTLY_REFUNDED` + - частичный возврат; + example: CHANGE_TIMETABLE + enum: + - ADDITIONAL_SERVICES + - EXCHANGE + - CHANGE_TIMETABLE + - PARTLY_REFUNDED + Transaction: + maxItems: 20 + type: array + description: Массив с транзакциями + items: + $ref: '#/components/schemas/TransactionItems' + TransactionItems: + required: + - currency + - dateTime + - maskedCardNumber + - rrn + - sum + type: object + properties: + sum: + type: number + description: Сумма оплаты в рублях + example: 800 + currency: + maxLength: 3 + type: string + description: Валюта оплаты + example: RUB + maskedCardNumber: + maxLength: 20 + type: string + description: Маскированный номер карты + example: 12345678******78912 + rrn: + maxLength: 255 + type: string + description: Уникальный идентификатор банковской транзакции + example: "1498745362575217925125545565" + tokenCode: + maxLength: 20 + type: string + description: Номер токена полученный при оплате через GooglePay/ApplePay + example: "65941241914" + dateTime: + type: string + description: Дата и время транзакции по МСК + format: date-time + example: 2023-10-05T14:30:00Z + cashback: + $ref: '#/components/schemas/Cashback' + description: Объект с содержимым транзакции + PaymentSum: + type: number + description: Сумма оплаты в рублях + example: 800 + MaskedCardNumber: + maxLength: 20 + type: string + description: Маскированный номер карты + example: 12345678******78912 + Rrn: + maxLength: 255 + type: string + description: Уникальный идентификатор банковской транзакции + example: "1498745362575217925125545565" + TokenCode: + maxLength: 20 + type: string + description: Номер токена полученный при оплате через GooglePay/ApplePay + example: "65941241914" + PaymentDateTime: + type: string + description: Дата и время транзакции по МСК + format: date-time + example: 2023-10-05T14:30:00Z + Cashback: + required: + - totalSum + type: object + properties: + totalSum: + type: number + description: Общая сумма кэшбека + example: 1850 + cashbackDetailList: + maxItems: 100 + type: array + description: Массив с детальной информацией о кэшбеке + items: + $ref: '#/components/schemas/CashbackDetailListItems' + description: Данные о кэшбеке + example: + totalSum: 1850 + cashbackDetailList: + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + TotalSumCashback: + type: number + description: Общая сумма кэшбека + example: 1850 + CashbackDetailList: + maxItems: 100 + type: array + description: Массив с детальной информацией о кэшбеке + items: + $ref: '#/components/schemas/CashbackDetailListItems' + CashbackDetailListItems: + type: object + properties: + contentId: + type: string + description: ИД товарной категории + example: "12" + sum: + type: number + description: Суммарный кэшбек за категорию + example: 800.0 + description: Объект с детальной информацией о кэшбеке + example: + contentId: "12" + sum: 800.0 + ContentId: + type: string + description: ИД товарной категории + example: "12" + CashSum: + type: number + description: Суммарный кэшбек за категорию + example: 800.0 + ErrorIncorrectStatus: + type: object + properties: + error: + type: string + description: Ошибка + example: incorrect_status + error_description: + type: string + description: Описание ошибки + example: Incorrect Status + description: Ошибка с сообщением + IncorrectError: + type: string + description: Ошибка + example: incorrect_status + IncorrectStatusDescription: + type: string + description: Описание ошибки + example: Incorrect Status + PostConfirmationRequest: + type: object + properties: + comment: + type: string + description: Комментарий к подтверждению + example: Подтвердить + paymentTransaction: + maxItems: 20 + type: array + description: Массив с транзакциями + items: + $ref: '#/components/schemas/PaymentTransactionItems' + cashback: + $ref: '#/components/schemas/Cashback' + example: + comment: Подтвердить + paymentTransaction: + - dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + - dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + - dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + - dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + - dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + cashback: + totalSum: 1850 + cashbackDetailList: + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + - contentId: "12" + sum: 800.0 + ConfirmationComment: + type: string + description: Комментарий к подтверждению + example: Подтвердить + PaymentTransaction: + maxItems: 20 + type: array + description: Массив с транзакциями + items: + $ref: '#/components/schemas/PaymentTransactionItems' + PaymentTransactionItems: + required: + - currency + - dateTime + - maskedCardNumber + - rrn + - sum + type: object + properties: + sum: + type: number + description: Сумма оплаты в рублях + example: 800 + currency: + maxLength: 3 + type: string + description: Валюта оплаты + example: RUB + maskedCardNumber: + maxLength: 20 + type: string + description: Маскированный номер карты + example: 12345678******78912 + rrn: + maxLength: 255 + type: string + description: Уникальный идентификатор банковской транзакции + example: "1498745362575217925125545565" + tokenCode: + maxLength: 20 + type: string + description: Номер токена полученный при оплате через GooglePay/ApplePay + example: "65941241914" + dateTime: + type: string + description: Дата и время транзакции по МСК + format: date-time + example: 2023-10-05T14:30:00Z + description: Информация об оплате + example: + dateTime: 2023-10-05T14:30:00Z + tokenCode: "65941241914" + sum: 800 + currency: RUB + maskedCardNumber: 12345678******78912 + rrn: "1498745362575217925125545565" + SuccessResponseConfirmOrder: + type: object + properties: + orderId: + maxLength: 50 + type: string + description: Идентификатор заказа в банке + example: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: + maxLength: 50 + type: string + description: Статус подтвержденного заказа + example: Confirmed + StatusConfirm: + maxLength: 50 + type: string + description: Статус подтвержденного заказа + example: Confirmed + SuccessConfirmAlreadyOrder: + type: object + properties: + orderId: + maxLength: 50 + type: string + description: Идентификатор заказа в банке + example: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: + type: string + description: Статус подтвержденного заказа + example: Order already confirmed + example: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Order already confirmed + StatusAlreadyConfirmed: + type: string + description: Статус подтвержденного заказа + example: Order already confirmed + PatchDeactivateRequest: + required: + - accountType + - sum + - sumRubEquivalent + type: object + properties: + accountType: + type: string + description: Тип бонусного счета для возврата + example: Мили + sumRubEquivalent: + type: number + description: Сумма возврата бонусными единицами в рублевом эквиваленте + example: 600 + sum: + type: number + description: Сумма возврата + example: 600 + comment: + type: string + description: Комментарий к возврату + nullable: true + example: Добровольный возврат + example: + sumRubEquivalent: 600 + accountType: Мили + sum: 600 + comment: Добровольный возврат + RefundAccountType: + type: string + description: Тип бонусного счета для возврата + example: Мили + RefundSumRubEquivalent: + type: number + description: Сумма возврата бонусными единицами в рублевом эквиваленте + example: 600 + RefundSum: + type: number + description: Сумма возврата + example: 600 + RefundComment: + type: string + description: Комментарий к возврату + nullable: true + example: Добровольный возврат + SuccessResponseBonus: + maxItems: 100 + type: array + description: Массив транзакций по заказу + items: + $ref: '#/components/schemas/SuccessResponseBonusItems' + SuccessResponseBonusItems: + required: + - balance + - typeName + - unitName + type: object + properties: + typeName: + maxLength: 50 + type: string + description: Наименование типа бонусного счета + nullable: true + example: AlfaTravel + balance: + type: integer + description: Баланс счета + format: int64 + nullable: true + example: 189594 + unitName: + maxLength: 50 + type: string + description: Наименование единиц измерения поощрений + nullable: true + example: Мили + description: Объект с полями транзакции по заказу + example: + balance: 189594 + unitName: Мили + typeName: AlfaTravel + TypeName: + maxLength: 50 + type: string + description: Наименование типа бонусного счета + nullable: true + example: AlfaTravel + Balance_1: + type: integer + description: Баланс счета + format: int64 + nullable: true + example: 189594 + UnitName: + maxLength: 50 + type: string + description: Наименование единиц измерения поощрений + nullable: true + example: Мили + PostRegistriesRequest: + required: + - admPid + - clientInf + - email + - expirationDate + - registryId + type: object + properties: + registryId: + maxLength: 36 + type: string + description: Идентификатор реестра + example: "039012000001000" + expirationDate: + type: string + description: "Дата и время (местное), до которого можно производить само\ + инкассацию по данному реестру (ISO 8601 с часовым поясом)" + format: date-time + example: 2025-08-05T11:00:00+03:00 + admPid: + pattern: "^\\d{8}$" + type: string + description: Номер АДМ (8 цифр) + example: "00330456" + clientStoreCode: + maxLength: 50 + type: string + description: Код магазина клиента + example: ShopCode001 + paymentAgentInf: + $ref: '#/components/schemas/EncashmentGroup' + bankPaymentAgentInf: + $ref: '#/components/schemas/EncashmentGroup' + clientInf: + $ref: '#/components/schemas/EncashmentGroup' + email: + maxLength: 254 + minLength: 1 + type: string + description: Адрес электронной почты клиента. Нужен для отправки чека об + операции + example: client@example.com + description: Объект для передачи данных о реестре раскассировки + example: + paymentAgentInf: + selfEncashmentAmount: "100.00" + accountNumber: "40821810801850000018" + clientInf: + selfEncashmentAmount: "100.00" + accountNumber: "40821810801850000018" + registryId: "039012000001000" + admPid: "00330456" + clientStoreCode: ShopCode001 + bankPaymentAgentInf: + selfEncashmentAmount: "100.00" + accountNumber: "40821810801850000018" + email: client@example.com + expirationDate: 2025-08-05T11:00:00+03:00 + EncashmentGroup: + required: + - accountNumber + - selfEncashmentAmount + type: object + properties: + accountNumber: + pattern: "^\\d{20}$" + type: string + description: Номер счёта + example: "40821810801850000018" + selfEncashmentAmount: + pattern: "^\\d+\\.\\d{1,2}$" + type: string + description: Сумма по реестру в рублях. Разделительный знак - точка. + example: "100.00" + example: + selfEncashmentAmount: "100.00" + accountNumber: "40821810801850000018" + PostRegistriesResponse: + required: + - registryId + type: object + properties: + registryId: + maxLength: 36 + type: string + description: Идентификатор реестра + example: "039012000001000" + example: + registryId: "039012000001000" + CancelRegistriesRequest: + required: + - registryIds + type: object + properties: + registryIds: + maxItems: 100 + type: array + description: Идентификаторы реестров раскассировки + example: + - "039012000001000" + - "039012000001001" + items: + maxLength: 36 + type: string + example: + registryIds: + - "039012000001000" + - "039012000001001" + CancelRegistriesResponse: + required: + - requestId + type: object + properties: + requestId: + type: string + description: Идентификатор запроса + example: 550e8400-e29b-41d4-a716-446655440000 + example: + requestId: 550e8400-e29b-41d4-a716-446655440000 + GetAdmResponse: + required: + - items + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_1' + items: + type: array + items: + $ref: '#/components/schemas/AdmDevice' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + items: + - statusDescription: Устройство полностью работоспособно + admSoftwareVersion: 2.1.8 + billValidatorSoftwareVersion: 1.0.4 + admPid: "00330456" + status: 1 + - statusDescription: Устройство полностью работоспособно + admSoftwareVersion: 2.1.8 + billValidatorSoftwareVersion: 1.0.4 + admPid: "00330456" + status: 1 + AdmDevice: + required: + - admPid + type: object + properties: + admPid: + type: string + description: Уникальный идентификатор устройства + example: "00330456" + status: + type: integer + description: | + Статус. Принимает возможные значения: + * `1` - Устройство полностью работоспособно; + * `2` - Работает, но есть проблемы; + * `3` - Устройство неработоспособно + example: 1 + enum: + - 1 + - 2 + - 3 + statusDescription: + type: string + description: Расшифровка статуса + example: Устройство полностью работоспособно + admSoftwareVersion: + type: string + description: Версия ПО АДМ + example: 2.1.8 + billValidatorSoftwareVersion: + type: string + description: Версия ПО купюроприемника + example: 1.0.4 + description: Данные АДМ + example: + statusDescription: Устройство полностью работоспособно + admSoftwareVersion: 2.1.8 + billValidatorSoftwareVersion: 1.0.4 + admPid: "00330456" + status: 1 + IndividualsPage: + required: + - items + - pagination + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_4' + items: + type: array + items: + $ref: '#/components/schemas/IndividualLead' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + items: + - createdAt: 2025-08-07T15:05:29.736Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: ИП Иванов Иван Иванович + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: inn + description: Подготовка документов + individualId: 6894c0b98f2def59337246b0 + updatedAt: 2025-08-07T15:05:36.376Z + status: IN_PROGRESS + - createdAt: 2025-08-07T15:05:29.736Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: ИП Иванов Иван Иванович + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: inn + description: Подготовка документов + individualId: 6894c0b98f2def59337246b0 + updatedAt: 2025-08-07T15:05:36.376Z + status: IN_PROGRESS + CreateIndividualRequest: + required: + - agreement + - city + - contactInfo + type: object + properties: + city: + $ref: '#/components/schemas/CreateIndividualRequest_city' + agreement: + type: boolean + description: Согласие на обработку персональных данных. + contactInfo: + $ref: '#/components/schemas/ContactInfo' + description: Тело запроса. + example: + agreement: true + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + city: + regionId: 6 + cityId: 0 + presenceCityTitle: presenceCityTitle + CreatedIndividualId: + required: + - individualId + type: object + properties: + individualId: + type: string + example: + individualId: individualId + Error_2: + required: + - error + - error_description + type: object + properties: + error: + type: string + example: invalid_token + error_description: + type: string + example: "The access token provided is expired, revoked, malformed, or invalid\ + \ for other reasons" + IndividualLead: + required: + - city + - clientName + - contactInfo + - createdAt + - description + - individualId + - status + - updatedAt + type: object + properties: + individualId: + type: string + example: 6894c0b98f2def59337246b0 + inn: + type: string + nullable: true + clientName: + type: string + example: ИП Иванов Иван Иванович + createdAt: + type: string + format: date-time + example: 2025-08-07T15:05:29.736Z + updatedAt: + type: string + format: date-time + example: 2025-08-07T15:05:36.376Z + contactInfo: + $ref: '#/components/schemas/ContactInfo' + status: + type: string + example: IN_PROGRESS + description: + type: string + example: Подготовка документов + city: + $ref: '#/components/schemas/IndividualLead_city' + example: + createdAt: 2025-08-07T15:05:29.736Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: ИП Иванов Иван Иванович + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: inn + description: Подготовка документов + individualId: 6894c0b98f2def59337246b0 + updatedAt: 2025-08-07T15:05:36.376Z + status: IN_PROGRESS + LlcsPage: + required: + - items + - pagination + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_4' + items: + type: array + items: + $ref: '#/components/schemas/LlcLead' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + items: + - createdAt: 2023-06-01T08:51:46.555Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: "7700000000" + description: Подготовка документов + llcId: 64785c22f344200bcfe1eb1e + updatedAt: 2023-06-01T08:51:58.408Z + status: IN_PROGRESS + - createdAt: 2023-06-01T08:51:46.555Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: "7700000000" + description: Подготовка документов + llcId: 64785c22f344200bcfe1eb1e + updatedAt: 2023-06-01T08:51:58.408Z + status: IN_PROGRESS + CreateLlcRequest: + required: + - agreement + - city + - clientName + - contactInfo + type: object + properties: + city: + $ref: '#/components/schemas/CreateIndividualRequest_city' + agreement: + type: boolean + description: Согласие на обработку персональных данных. + contactInfo: + $ref: '#/components/schemas/ContactInfo' + clientName: + type: array + description: "" + example: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + items: + $ref: '#/components/schemas/ClientNameItem' + description: Тело запроса. + example: + agreement: true + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + city: + regionId: 6 + cityId: 0 + presenceCityTitle: presenceCityTitle + clientName: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + CreatedLlcId: + required: + - llcId + type: object + properties: + llcId: + type: string + example: + llcId: llcId + LlcLead: + required: + - city + - clientName + - contactInfo + - createdAt + - description + - llcId + - status + - updatedAt + type: object + properties: + llcId: + type: string + example: 64785c22f344200bcfe1eb1e + inn: + type: string + nullable: true + example: "7700000000" + createdAt: + type: string + format: date-time + example: 2023-06-01T08:51:46.555Z + updatedAt: + type: string + format: date-time + example: 2023-06-01T08:51:58.408Z + contactInfo: + $ref: '#/components/schemas/ContactInfo' + clientName: + type: array + description: "" + example: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + items: + $ref: '#/components/schemas/ClientNameItem' + status: + type: string + example: IN_PROGRESS + description: + type: string + example: Подготовка документов + city: + $ref: '#/components/schemas/IndividualLead_city' + example: + createdAt: 2023-06-01T08:51:46.555Z + contactInfo: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + clientName: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + city: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + inn: "7700000000" + description: Подготовка документов + llcId: 64785c22f344200bcfe1eb1e + updatedAt: 2023-06-01T08:51:58.408Z + status: IN_PROGRESS + ManagerCitiesPage: + required: + - items + - pagination + type: object + properties: + pagination: + $ref: '#/components/schemas/Pagination_4' + items: + type: array + items: + $ref: '#/components/schemas/City_2' + example: + pagination: + offset: 0 + limit: 10 + totalCount: 1 + items: + - cityName: Москва + regionId: 77 + cityId: 1 + - cityName: Москва + regionId: 77 + cityId: 1 + MonthPeriod: + type: string + description: "Отчётный месяц в формате ISO 8601 (YYYY-MM-DDThh:mm:ss.SSSZ).\ + \ Рекомендуется указывать первое число целевого месяца с нулевым временем\ + \ (например, 2025-08-01T00:00:00.000Z). Не старше 6 месяцев от текущей дат\ + ы." + example: 2025-08-01T00:00:00.000Z + ClientsResponse: + type: object + properties: + clients: + type: array + description: Список ИНН клиентов с продажами по указанным продуктам за месяц; + может быть null при отсутствии продаж. + nullable: true + items: + type: string + description: Схема ClientsResponse. + example: + clients: + - "782740504" + - "782740502" + - "782740508" + SalesResponse: + type: object + properties: + sales: + type: array + description: Список наименований успешно проданных клиенту продуктов по + ИНН за заданный месяц; может быть null при отсутствии продаж. + nullable: true + items: + type: string + description: Схема SalesResponse. + example: + sales: + - РКО + - ТА + - ИА + ComplianceScoreResponse: + required: + - boundaries + - inn + - rawScore + - riskLevel + type: object + properties: + inn: + maxLength: 12 + minLength: 10 + type: string + description: ИНН организаци + rawScore: + type: number + description: Вероятность применения комплаенс-мер (от 0 до 1) + format: float + example: 0.2094234 + riskLevel: + type: string + description: Оценка в терминах уровня риска + example: low + enum: + - low + - medium + - high + boundaries: + $ref: '#/components/schemas/ComplianceScoreResponse_boundaries' + example: + riskLevel: low + inn: inn + rawScore: 0.2094234 + boundaries: + high: 0.65 + low: 0.32 + SimplePage: + type: object + properties: + limit: + type: integer + description: Количество записей на одной странице + example: 1000 + offset: + type: integer + description: "Количество записей в списке, которые были пропущены" + example: 0 + totalCount: + type: integer + description: Общее количество записей + example: 10000 + description: Данные пагинации + example: + offset: 0 + limit: 1000 + totalCount: 10000 + Meta_1: + type: object + properties: + totalPages: + maximum: 5000 + minimum: 1 + type: number + description: Указывает на количество передаваемых страниц + format: int32 + example: 1 + additionalProperties: false + description: "Дополнительные данные о запросе. «totalPages», указывает на ко\ + личество передаваемых страниц. Если передается более одной страницы, то эл\ + емент «totalPages» обязательно присутствует." + example: + totalPages: 1 + MerchantInfo: + type: object + properties: + merchantId: + maxLength: 40 + minLength: 1 + pattern: "^[A-Z0-9]{1,40}$" + type: string + description: "Уникальный и неизменный идентификатор, используемый для ид\ + ентификации ресурса" + example: THIS01IS02MERCHANTID0XXX + merchantCategoryCode: + pattern: "^\\d{3,4}$" + type: string + description: "Код категории соответствует ISO 18245 и относится к типу у\ + слуг или товаров, которые продавец предоставляет для транзакции" + example: "1234" + additionalProperties: false + description: Информация о продавце + CountryCodeAlfa3: + pattern: "^[A-Z]{3,3}$" + type: string + description: Код страны в формате ISO 3166-1 alpha-3 + example: RUS + PlainCardData: + required: + - PAN + type: object + properties: + PAN: + pattern: "^[0-9]{4}$" + type: string + description: "Маскированный учетный номер карты (PAN) или номер карты, о\ + граниченный последними 4 цифрами." + example: "0001" + expiryDate: + description: Дата окончания срока действия карты + example: 12/2025 + allOf: + - $ref: '#/components/schemas/ISOYearMonth' + additionalProperties: false + description: "Данные платежной карты, ассоциированной со счетом" + Pagination_4: + required: + - limit + - offset + - totalCount + type: object + properties: + limit: + type: integer + example: 10 + offset: + type: integer + example: 0 + totalCount: + type: integer + example: 1 + example: + offset: 0 + limit: 10 + totalCount: 1 + ContactInfo: + required: + - email + - firstName + - lastName + - phone + type: object + properties: + phone: + pattern: "^7\\d{10}$" + type: string + description: "Телефон заявителя в формате 7XXXXXXXXXX. Формат: только ци\ + фры, начинается с 7, всего 11 цифр." + example: "79000000000" + lastName: + type: string + description: Фамилия заявителя. + example: Иванов + middleName: + type: string + description: Отчество заявителя (при наличии). + example: Иванович + firstName: + type: string + description: Имя заявителя. + example: Иван + email: + type: string + description: E-mail заявителя. + format: email + example: ivan@example.ru + description: "Контактная информация заявителя: ФИО и контактные данные." + example: + lastName: Иванов + firstName: Иван + phone: "79000000000" + middleName: Иванович + email: ivan@example.ru + ClientNameArray: + type: array + description: "" + example: + - language: RU + full: Общество с ограниченной Ответственностью Альфа + short: ООО Альфа + - language: EN + full: Alfa Limited Liability Company + short: Alfa LLC + items: + $ref: '#/components/schemas/ClientNameItem' + City_2: + required: + - cityId + - cityName + - regionId + type: object + properties: + cityId: + type: integer + description: Идентификатор города + example: 1 + regionId: + type: integer + description: Идентификатор региона + example: 77 + cityName: + type: string + description: Наименование города + example: Москва + example: + cityName: Москва + regionId: 77 + cityId: 1 + ClientNameItem: + required: + - full + - language + - short + type: object + properties: + language: + type: string + enum: + - RU + - EN + full: + type: string + short: + type: string + description: "" + _gd_v1_accounts__accountNumber__status_get_200_response: + type: object + properties: + isAlfaBank: + type: boolean + description: Признак действующего счета в Альфа-Банке + example: true + example: + isAlfaBank: true + verifySms_200_response: + oneOf: + - $ref: '#/components/schemas/VerifySmsFormCreationResponse' + - $ref: '#/components/schemas/VerifySmsFormCompletionResponse' + resendSms_200_response: + oneOf: + - $ref: '#/components/schemas/ResendSmsCreationResponse' + - $ref: '#/components/schemas/ResendSmsCompletionResponse' + CreateTravelOrder_request: + required: + - order + type: object + properties: + order: + $ref: '#/components/schemas/PostOrderTravel' + CreateAfishaOrder_request: + required: + - order + type: object + properties: + order: + $ref: '#/components/schemas/PostOrderAfisha' + UpdateTravelOrder_request: + required: + - order + type: object + properties: + order: + $ref: '#/components/schemas/PutOrderTravel' + ClientInfo_organizationForm: + required: + - code + - fullName + - shortName + - type + type: object + properties: + fullName: + type: string + description: Организационно-правовая форма организации клиента + example: Общество с ограниченной ответственностью + shortName: + type: string + description: Краткое наименование ОПФ + example: ООО + type: + type: string + description: Тип ОПФ + example: "2014" + code: + type: string + description: Код ОПФ + example: "12300" + example: + code: "12300" + fullName: Общество с ограниченной ответственностью + shortName: ООО + type: "2014" + Account_bank: + type: object + properties: + bic: + type: string + description: БИК банка + example: "044525593" + description: "Информация об отделении банке, где открыт счет" + example: + bic: "044525593" + Links_inner: + type: object + properties: + href: + type: string + description: Cсылка ведущая на следующую/предыдущую страницу + example: accountNumber=40702810500006103990&statementDate=2018-03-15&page=3 + rel: + type: string + description: | + Признак страницы * `prev` - Предыдущая страница * `next` - Следующая страница + enum: + - prev + - next + example: + rel: prev + href: accountNumber=40702810500006103990&statementDate=2018-03-15&page=3 + Transactions_inner: + type: object + properties: + amount: + $ref: '#/components/schemas/Amount' + amountRub: + $ref: '#/components/schemas/AmountRub' + correspondingAccount: + type: string + description: Корреспондирующий счёт + example: "30101810400000000225" + direction: + type: string + description: | + Направление транзакции * `CREDIT` - Поступление на счет * `DEBIT` - Списание со счета + enum: + - DEBIT + - CREDIT + documentDate: + type: string + description: Дата документа + example: 2021-10-07 + filial: + type: string + description: Наименование филиала + example: АО "АЛЬФА-БАНК" + number: + type: string + description: Номер операции + example: "1843" + operationCode: + type: string + description: | + Тип операции * `01` - Платежное поручение/Валютный перевод * `02` - Платежное требование * `03` - Расходный кассовый ордер/Расходный кассовый чек * `04` - Приходный кассовый ордер/Приходный кассовый чек/Объявление на взнос наличными * `06` - Инкассовое поручение * `08` - Аккредитив * `09` - Мемориальный ордер * `16` - Платежный ордер * `17` - Банковский ордер + enum: + - "01" + - "01" + - "02" + - "03" + - "03" + - "04" + - "04" + - "04" + - "06" + - "08" + - "09" + - "16" + - "17" + x-enum-varnames: + - PAYMENT + - CURRENCY_PAYMENT + - PAYMENT_REQUEST + - DEBIT_ORDER + - DEBIT_CACH_CHECK + - CACH_CONTRIBUTION + - CREDIT_CACH_CHECK + - CREDIT_ORDER + - COLLECTION_LETTER + - AKKREDITIV + - MEMORY_ORDER + - PAYMENT_ORDER + - BANK_ORDER + operationDate: + type: string + description: Дата и время операции + example: 2018-12-31T00:00:00Z + paymentPurpose: + type: string + description: Назначение платежа + example: НДС не облагается + priority: + type: string + description: Очередность платежа + example: "5" + revaln: + type: string + description: | + Признак операции переоценки * `ПК` - Пересчет курса * `ДП` - Дооценка руб. покрытия + enum: + - ПК + - ДП + x-enum-varnames: + - PK + - DP + uuid: + type: string + description: Уникальный идентификатор операции + example: 55daccdf-de87-3879-976c-8b8415c8caf9 + transactionId: + type: string + description: Идентификатор операции + example: 1211206MOCO#DS0000017 + debtorCode: + type: string + description: Код дебитора + example: "0" + extendedDebtorCode: + type: string + description: Расширенный код дебитора + example: "50012008" + rurTransfer: + $ref: '#/components/schemas/RurTransfer' + swiftTransfer: + $ref: '#/components/schemas/SwiftTransfer' + curTransfer: + $ref: '#/components/schemas/CurTransfer' + example: + documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW\ + \ RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + swiftTransfer: + bankOperationCode: CRED + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + transactionTypeCode: S01 + instructionCode: instructionCode + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageIdentifier: S000013082900014 + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + beneficiaryCustomerName: ООО Ромашка + instructedAmount: "USD70,00" + transactionRelatedReference: transactionRelatedReference + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + orderingInstitutionAccount: ABOCBNBJ080 + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + intermediaryBankAccount: COBADEFF + transactionReferenceNumber: 69528 + orderingInstitutionOption: D + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW\ + \ RUSSIAN FEDERATION" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + senderCharges: "USD7,03" + receiverCharges: receiverCharges + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + ResponseSignatureRsaXmlSignedInfo_ds_CanonicalizationMethod: + type: object + properties: + Algorithm: + type: string + example: http://www.w3.org/2001/10/xml-exc-c14n# + xml: + attribute: true + ResponseSignatureRsaXmlSignedInfo_ds_SignatureMethod: + type: object + properties: + Algorithm: + type: string + example: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + xml: + attribute: true + ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_Transforms_ds_Transform_inner: + oneOf: + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransform1' + - $ref: '#/components/schemas/ResponseSignatureRsaXmlTransform2' + ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_Transforms: + type: object + properties: + ds:Transform: + type: array + items: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_Transforms_ds_Transform_inner' + ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_DigestMethod: + type: object + properties: + Algorithm: + type: string + example: http://www.w3.org/2001/04/xmldsig-more#sha384 + xml: + attribute: true + ResponseSignatureRsaXmlSignedInfo_ds_Reference: + type: object + properties: + URI: + type: string + example: "" + xml: + attribute: true + ds:Transforms: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_Transforms' + ds:DigestMethod: + $ref: '#/components/schemas/ResponseSignatureRsaXmlSignedInfo_ds_Reference_ds_DigestMethod' + ds:DigestValue: + type: string + example: oDifxB42SMw0vIERQ8nDsPblrSYSmu9jiJoT+BcO9J1hIEsj/h00cK340jXmsz4+ + ResponseSignatureRsaXmlTransform1_allOf: + type: object + properties: + Algorithm: + type: string + example: http://www.w3.org/2000/09/xmldsig#enveloped-signature + xml: + attribute: true + ResponseSignatureRsaXmlTransform2_allOf: + type: object + properties: + Algorithm: + type: string + example: http://www.w3.org/2001/10/xml-exc-c14n# + xml: + attribute: true + ResponseSignatureRsaXmlKeyInfo_ds_X509Data: + type: object + properties: + ds:X509Certificate: + type: string + example: |- + MIIGMzCCBBugAwIBAgIIQ+Ua6h49X/kwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8w + DQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazEl + MCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0 + Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsu + cnUwHhcNMjQwNTI3MTMzNTAwWhcNMjkwNTI3MTMzNTAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNV + BAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYD + VQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29y + ZVJTQSBTaWduZXIyIDIwNDggYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBh + bGZhYmFuay5ydTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbaUlic4XF47DJtoFQK + Nnd46jvaoE9pyxByuEKQkZY8Na5XWNuyr5ZALF6RTYXRS+i2wqig+zsGhEKG5rM2VZFJB4p6Vvwb + ULzDeH08tEw01hvnIiUFxrlVlpMIM649rLaMUTZnh8RKq23WkvDxPaEEeLV0f0sgeHpBf2nV7ZeM + 4w6LdC2T/hnYAy7VxIS+BN2nDGOIePqh+lGgUZIHY9cO3IbN7yWSQQSC7hQ696RC9L5vWedOXb6C + myWlFsuOnAgp+O3z2U1wbovCQ48CU8VprzjLorw/UTz/qJr7uGGICuY7M1Go7qLvICsHclkKqvRc + CMLBGxdg6RBkA+6t96cCAwEAAaOCAScwggEjMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFp1la5Q + GzpdMD7SCyadt9CVfElrMAsGA1UdDwQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAwYIKwYBBQUH + AwQwgccGA1UdHwSBvzCBvDA8oDqgOIY2aHR0cDovL2FydGFwcC9hcnRpZmFjdG9yeS9UcnVzdENv + cmUvQ1JMcy90cnVzdGNvcmUuY3JsMDqgOKA2hjRodHRwOi8vaGF2ZW4ubW9zY293LmFsZmFpbnRy + YS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMECgPqA8hjpodHRwOi8vczAxZHBydXByYnMubW9zY293 + LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMA0GCSqGSIb3DQEBCwUAA4ICAQARCvm8 + JwBOGonGKMlnwyxnFX2aV1qIkzMgo7ILaCXT/MybvPH/3GQByBOUsASFU7cod57qEOOyQSN/JTQ/ + ZdKz3B8goGoO1XC/toybaTib92Dru7XyiJAeOLHksDjMQ7U6Xgk/51xoPa6AvZyOUWNW0KUdQFWl + fyJeH+Gt4Xr1OH+LYuUMhiVubUPn+edW/PW8WTzlpjvd55/e69YViSJBuNenV0cmxKe/xWD7ZnfG + fBsf+Sy/xhfjP0nFd7qANeQJXmb07gl7zJUyV0oK7fXyHO7Rg2wVcWEr8p9uS/sTS0ZnXJZKN3/O + O+zp9UPM23uzZNuySsBbc7QNlJ3c8GLL/R93xvE3BNV+DtZVbu7xaqcWZmFEnfp0iTVCfMC3d9Ci + g+KZ5NKBQp+vB0A4+vj8jO/ZCCjtho3nqeJ+exO2AHgLYj6XaeCTed4fW0ENt0XWNrFaVW/wRyHO + XvEN8Ocj8LV5Xtwh6xPuwSbas2VL4v7V50O7V5RA4ZucdpdmRj5z/qkqkirGRcWnf+UWwjniI+Bz + CGlsPjGJmGgl8OjGUnb/vZ4fN1g2QVBcS1riln0mQDPbaBJNtFOSc3GCh+HttX075tinnux348Yg + qsHeKfsVZ6+5gmrumdaS8uN/L/cgFtPJFfwpbz5YGq98owU8BVlodP1eM8C5eEPU1X0BGQ== + TransactionsCorrespondent_inner: + type: object + properties: + amount: + $ref: '#/components/schemas/Amount' + amountRub: + $ref: '#/components/schemas/AmountRub' + correspondingAccount: + type: string + description: Корреспондирующий счёт + example: "30101810400000000225" + direction: + type: string + description: | + Направление транзакции * `CREDIT` - Поступление на счет * `DEBIT` - Списание со счета + enum: + - DEBIT + - CREDIT + documentDate: + type: string + description: Дата документа + example: 2021-10-07 + filial: + type: string + description: Наименование филиала + example: АО "АЛЬФА-БАНК" + number: + type: string + description: Номер операции + example: "1843" + operationCode: + type: string + description: | + Тип операции * `01` - Платежное поручение/Валютный перевод * `02` - Платежное требование * `03` - Расходный кассовый ордер/Расходный кассовый чек * `04` - Приходный кассовый ордер/Приходный кассовый чек/Объявление на взнос наличными * `06` - Инкассовое поручение * `08` - Аккредитив * `09` - Мемориальный ордер * `16` - Платежный ордер * `17` - Банковский ордер + enum: + - "01" + - "02" + - "03" + - "04" + - "06" + - "08" + - "09" + - "16" + - "17" + operationDate: + type: string + description: Дата и время операции + example: 2018-12-31T00:00:00Z + paymentPurpose: + type: string + description: Назначение платежа + example: НДС не облагается + priority: + type: string + description: Очередность платежа + example: "5" + revaln: + type: string + description: | + Признак операции переоценки * `ПК` - Пересчет курса * `ДП` - Дооценка руб. покрытия + enum: + - ПК + - ДП + uuid: + type: string + description: Уникальный идентификатор операции + example: 55daccdf-de87-3879-976c-8b8415c8caf9 + transactionId: + type: string + description: Идентификатор операции + example: 1211206MOCO#DS0000017 + debtorCode: + type: string + description: Код дебитора + example: "0" + extendedDebtorCode: + type: string + description: Расширенный код дебитора + example: "50012008" + rurTransfer: + $ref: '#/components/schemas/RurTransfer' + curTransfer: + $ref: '#/components/schemas/CurTransfer' + example: + documentDate: 2021-10-07 + operationDate: 2018-12-31T00:00:00Z + amount: + amount: 1.01 + currencyName: USD + filial: АО "АЛЬФА-БАНК" + correspondingAccount: "30101810400000000225" + debtorCode: "0" + curTransfer: + payerBankCorrAccount: "30101810200000000593" + intermediaryBankOption: D + intermediaryBankName: АО "АЛЬФА-БАНК" + orderingCustomerAccount: /08251801040004813 + orderingCustomerName: ООО Радуга + instructionCode: instructionCode + messageType: "103" + exchangeRate: "67,74" + beneficiaryBankName: АО \"АЛЬФА-БАНК\" + messageOriginator: SABRRU2P + receiverCorrespondentAccount: "30101810400000000000" + regulatoryReporting: /N10/NS/N4/12345678901234567890/N5/12345678901/N6/TP/N7 + МS.05.2003/N8/123456789012345/N9/12.05.2003 + beneficiaryBankAccount: LOYDGB21323 + instructedAmount: "USD70,00" + payeeBankCorrAccount: "30101810200000000593" + transactionRelatedReference: transactionRelatedReference + senderCorrespondentName: "CITIBANK N.A. NEW YORK,NY" + senderCorrespondentAccount: BOTKGB2L + valueDateCurrencyInterbankSettledAmount: "130824EUR5447,34" + senderCorrespondentOption: D + intermediaryBankAccount: COBADEFF + payerInn: "7728168971" + senderToReceiverInformation: /NZP/OT 15.03.2009. NDS NE OBLAGAETSYA + receiverCorrespondentName: "JSC ROSSELKHOZBANK 3, GAGARINSKY PEREULOK MOSCOW\ + \ RUSSIAN FEDERATION" + payeeBankBic: "9611925" + senderCharges: "USD7,03" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + bankOperationCode: CRED + transactionTypeCode: S01 + payeeName: Наименование получателя + messageReceiveTime: 15-05-27 13:21 + messageDestinator: LAPBLV2X + messageIdentifier: S000013082900014 + beneficiaryCustomerName: ООО Ромашка + payerName: Гаврилов Добрыня Петрович + urgent: URGENT + orderingInstitutionName: АО "АЛЬФА-БАНК" + receiverCorrespondentOption: D + orderingInstitutionAccount: ABOCBNBJ080 + messageSendTime: 15-05-27 13:21 + orderingCustomerOption: K + detailsOfCharges: OUR + transactionReferenceNumber: 69528 + payerKpp: "770801001" + payerBankName: АО \"АЛЬФА-БАНК\" + orderingInstitutionOption: D + payerAccount: "40802810401300015422" + payeeBankName: АО \"АЛЬФА-БАНК\" + beneficiaryBankOption: D + remittanceInformation: PAYMENT ACC AGREEMENT 1 DD 29.11.2018 FOR WATCHES + beneficiaryCustomerAccount: /40702810701300000761 + payerBankBic: "044525593" + payeeInn: "7728168971" + receiverCharges: receiverCharges + operationCode: "01" + amountRub: + amount: 1.01 + currencyName: USD + extendedDebtorCode: "50012008" + priority: "5" + uuid: 55daccdf-de87-3879-976c-8b8415c8caf9 + revaln: ПК + transactionId: 1211206MOCO#DS0000017 + rurTransfer: + payerBankCorrAccount: "30101810200000000593" + departmentalInfo: + drawerStatus101: "1" + oktmo: "11605000" + kbk: "39210202010061000160" + taxPeriod107: МС.03.2016 + docNumber108: "123" + reasonCode106: ТП + docDate109: 31.12.2018 + uip: "32221003200126505006" + paymentKind110: "1" + payerKpp: "770801001" + receiptDate: 2018-12-31 + deliveryKind: электронно + payerBankName: АО \"АЛЬФА-БАНК\" + payerInn: "7728168971" + valueDate: 2018-12-31 + cartInfo: + documentCode: documentCode + documentDate: 2019-10-19T06:33:47.923Z + restAmount: restAmount + documentNumber: documentNumber + documentContent: documentContent + paymentNumber: paymentNumber + payerAccount: "40802810401300015422" + payeeName: Наименование получателя + payeeBankName: АО \"АЛЬФА-БАНК\" + payeeBankBic: "9611925" + payerBankBic: "044525593" + purposeCode: "1" + payeeInn: "7728168971" + payerName: Гаврилов Добрыня Петрович + payeeBankCorrAccount: "30101810200000000593" + payeeKpp: "770801001" + payeeAccount: "40802810401300015422" + payingCondition: payingCondition + number: "1843" + paymentPurpose: НДС не облагается + direction: DEBIT + DownloadFileLinks_inner: + type: object + properties: + url: + type: string + description: Ссылка на скачивание файла. Ссылка доступна только если status + = SUCCEED . + example: https://baas.alfabank.ru/filebox/secure-file-transfer.outgoing-files.to-processing/f190bfef-aad6-ce9b-9224-f11ef60564cb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 + method: + type: string + description: Метод для скачивания файла + example: GET + example: + method: GET + url: https://baas.alfabank.ru/filebox/secure-file-transfer.outgoing-files.to-processing/f190bfef-aad6-ce9b-9224-f11ef60564cb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 + AccountResponse_Data: + description: Полезная нагрузка ответа + allOf: + - $ref: '#/components/schemas/DataAccountResponse' + AccountResponse_Links: + description: Раздел для указания ссылок + example: + self: https://sb.example.ru/v1.3/example + allOf: + - $ref: '#/components/schemas/Links_1' + AccountResponse_Meta: + description: Раздел метаданных + allOf: + - $ref: '#/components/schemas/Meta' + Account_1_Owner: + description: Информация о владельце счета + allOf: + - $ref: '#/components/schemas/PartyIdentification' + Account_1_Servicer: + oneOf: + - $ref: '#/components/schemas/BranchAndFinancialInstitutionInformationPilot' + - $ref: '#/components/schemas/BranchAndFinancialInstitutionInformation' + BranchAndFinancialInstitutionInformationPilot_CorrespondentAccount: + required: + - identification + - schemeName + type: object + properties: + schemeName: + description: Наименование схемы идентификации счета + allOf: + - $ref: '#/components/schemas/AccountIdentificationCode' + identification: + maxLength: 256 + minLength: 1 + pattern: "^[\\w\\W]{1,256}$" + type: string + description: "Идентификатор счета соответствующий схеме идентификации, и\ + звестный владельцу счета (номер банковского счета, номер карты, номер\ + \ телефона ...)" + example: "40817810621234570000" + additionalProperties: false + description: Корреспондентский счет + BranchAndFinancialInstitutionInformationPilot_PostalAddress: + required: + - addressLine + type: object + properties: + addressLine: + maxItems: 2 + minItems: 0 + type: array + description: Строка адреса + example: + - Адрес в виде строки + - вторая часть строки адреса + items: + maxLength: 70 + minLength: 1 + pattern: "^[\\w\\W]{1,70}$" + type: string + description: Строка адреса + additionalProperties: false + description: "Адрес отделения, обслуживающего счет" + StatementResponse_Data: + description: Полезная нагрузка ответа + allOf: + - $ref: '#/components/schemas/Statement_2' + StatementResponse_Links: + description: Раздел для указания ссылок + allOf: + - $ref: '#/components/schemas/Links_1' + Statement_2_TransactionsSummary: + description: Обороты по кредиту и дебету + allOf: + - $ref: '#/components/schemas/TransactionsSummary' + CashBalance_Amount: + description: Сумма остатка + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount' + TransactionsSummary_TotalCreditEntries: + description: Обороты по кредиту + example: + numberOfEntries: "2" + sum: "100.00" + currency: RUB + allOf: + - $ref: '#/components/schemas/NumberAndSumOfTransactions' + TransactionsSummary_TotalDebitEntries: + description: Обороты по дебету + example: + numberOfEntries: "2" + sum: "1500.00" + currency: RUB + allOf: + - $ref: '#/components/schemas/NumberAndSumOfTransactions' + ReportEntry_Amount: + description: "Информация о сумме и валюте операции по счету для данной запис\ + и (Примечание - TransactionAmount,ChargeAmount,InstructedAmount - это дета\ + ли данного реквизита)" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount' + ReportEntry_TransactionAmount: + description: Сумма в валюте исходной операции по счету + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount' + ReportEntry_ChargeAmount: + description: Комиссия за операции по счету + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount' + ReportEntry_InstructedAmount: + description: "Сумма денег и информации об обменом курсе, подлежащая перевод\ + у между плательщиком и получателем денежных средств до вычета расходов, вы\ + раженная в валюте обозначенной инициирующей стороной в случае, если указан\ + ная сумма и/или валюта отличаются от суммы и/или валюты операции по счету" + allOf: + - $ref: '#/components/schemas/AmountAndCurrencyExchangeDetails' + ReportEntry_BankTransactionCode: + description: Подробная информация для полной идентификации собственного банковского + кода операции по счету + allOf: + - $ref: '#/components/schemas/BankTransactionCode' + ReportEntry_PaymentTypeInformation: + description: Информация о типе платежа + allOf: + - $ref: '#/components/schemas/PaymentTypeInformation' + ReportEntry_UltimateDebtor: + description: Фактический плательщик + allOf: + - $ref: '#/components/schemas/PartyIdentification' + ReportEntry_Debtor: + description: Плательщик + allOf: + - $ref: '#/components/schemas/PartyChoice' + ReportEntry_DebtorAgent: + description: "Финансовое организация, обслуживающая счет плательщика" + allOf: + - $ref: '#/components/schemas/BranchAndFinancialInstitutionIdentification' + ReportEntry_DebtorAgentAccount: + description: Однозначная идентификация счета плательщика у обслуживающего его + банка в платежной цепочке + allOf: + - $ref: '#/components/schemas/CashAccount' + ReportEntry_DebtorAccount: + description: "Уникальная идентификация счета плательщика, на котором будет с\ + делана дебетовая запись в результате операции" + allOf: + - $ref: '#/components/schemas/CashAccount' + ReportEntry_IntermediaryAgent: + description: "Банк-посредник, находящийся между банком плательщика и банком\ + \ получателя денежных средств" + allOf: + - $ref: '#/components/schemas/BranchAndFinancialInstitutionIdentification' + ReportEntry_IntermediaryAgentAccount: + description: Счет банка-посредника + allOf: + - $ref: '#/components/schemas/CashAccount' + ReportEntry_CreditorAgent: + description: "Финансовое организация, обслуживающая счет получателя денежны\ + х средств" + allOf: + - $ref: '#/components/schemas/BranchAndFinancialInstitutionIdentification' + ReportEntry_CreditorAccount: + description: "Идентификатор счета получателя средств, на котором будет прове\ + дена запись о кредите в результате операции" + allOf: + - $ref: '#/components/schemas/CashAccount' + ReportEntry_CreditorAgentAccount: + description: "Однозначная идентификация счета банка получателя денежных сред\ + ств у обслуживающего его банка, по которому будет выполнена кредитовая зап\ + ись в результате платежной операции" + allOf: + - $ref: '#/components/schemas/CashAccount' + ReportEntry_Creditor: + description: Получатель денежных средств + allOf: + - $ref: '#/components/schemas/PartyChoice' + ReportEntry_UltimateCreditor: + description: Фактический получатель денежных средств + allOf: + - $ref: '#/components/schemas/PartyIdentification' + ReportEntry_CardTransaction: + description: |- + Предоставляет данные по карте (номер, платежная система), терминалу + (номер, идентификатор) и транзакционные данные, используемые для + уникальной идентификации операции по карте + allOf: + - $ref: '#/components/schemas/CardTransaction18' + ReportEntry_RemittanceInformation: + description: "Предоставляемая информация, позволяющая сопоставить запись с п\ + озициями, для которых предназначен перевод, такими как коммерческие счета\ + \ в системе дебиторской задолженности" + allOf: + - $ref: '#/components/schemas/RemittanceInformation' + AmountAndCurrencyExchangeDetails_Amount: + description: "Сумма денег, подлежащая переводу между плательщиком и получате\ + лем денежных средств до вычета расходов, выраженная в валюте обозначенной\ + \ инициирующей стороной" + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount' + AmountAndCurrencyExchangeDetails_CurrencyExchange: + required: + - Amount + description: "Набор элементов, используемые для указания информации об обмен\ + ом курсе. Использование: Это может быть либо встречная сумма, указанная в\ + \ сделке с иностранной валютой, либо результат информации о валюте, примен\ + енной к указанной сумме, до вычета расходов" + allOf: + - $ref: '#/components/schemas/CurrencyExchange' + PartyChoice_Agent: + type: object + description: "Информация об участнике, используемая для идентификации финанс\ + овой организации" + allOf: + - $ref: '#/components/schemas/BranchAndFinancialInstitutionInformation' + PartyChoice_Party: + description: "Информация об участнике, используемая для идентификации юридич\ + еского или физического лица" + allOf: + - $ref: '#/components/schemas/PartyIdentification' + CardTransaction18_POI: + description: "Физический или логический карточный платежный терминал, состоя\ + щий из программного обеспечения и аппаратной части" + allOf: + - $ref: '#/components/schemas/PointOfInteraction1' + CardTransaction18_Transaction: + description: "Сведения об отдельной операции по карте, записанные на POI-тер\ + минале (точке взаимодействия)" + allOf: + - $ref: '#/components/schemas/CardIndividualTransaction2' + PaymentCard4_PlainCardData: + description: "Конфиденциальные данные, связанные с выполнением операции по к\ + арте" + allOf: + - $ref: '#/components/schemas/PlainCardData1' + PaymentCard4_CardBrand: + description: Брендовое наименование карты + allOf: + - $ref: '#/components/schemas/GenericIdentification32' + PlainCardData1_CardSecurityCode: + description: "Код безопасности карты (CSC), связанный с выполнением операции\ + \ по карте" + allOf: + - $ref: '#/components/schemas/CardSecurityInformation1' + PointOfInteraction1_Identification: + description: "Уникальный и однозначный идентификатор (карты/POI-терминала),\ + \ присвоенный идентифицирующей организацией" + allOf: + - $ref: '#/components/schemas/GenericIdentification32' + CardIndividualTransaction2_TransactionIdentification: + description: "Идентификатор операции, назначенной POI (точка взаимодействия)" + allOf: + - $ref: '#/components/schemas/TransactionIdentifier1' + CardIndividualTransaction2_Product_inner: + allOf: + - $ref: '#/components/schemas/Product2' + RemittanceInformation_CreditorReferenceInformation: + description: Информация от получателя денежных средств + allOf: + - $ref: '#/components/schemas/CreditorReferenceInformation' + RemittanceInformation_TaxRemittance: + description: "Информация о платеже, которая связана с оплатой налогов" + allOf: + - $ref: '#/components/schemas/TaxInformation' + TaxInformation_creditor: + description: Налоговая информация о получателе средств + allOf: + - $ref: '#/components/schemas/TaxParty' + TaxInformation_debtor: + description: Налоговая информация о плательщике + allOf: + - $ref: '#/components/schemas/TaxParty' + TaxInformation_Record: + description: Дополнительные налоговые реквизиты + allOf: + - $ref: '#/components/schemas/TaxRecord' + TaxRecord_TaxAmount: + description: Информация о НДС + allOf: + - $ref: '#/components/schemas/TaxAmount' + StatementInitRequest_Data: + allOf: + - $ref: '#/components/schemas/DataStatementInitRequest' + DataStatementInitRequest_Statement: + description: Объект запроса на создание ресурса выписки + allOf: + - $ref: '#/components/schemas/StatementInitType' + StatementInitResponse_Data: + description: Полезная нагрузка ответа + allOf: + - $ref: '#/components/schemas/DataStatementInitResponse' + DataStatementInitResponse_Statement: + description: Ресурс выписки + allOf: + - $ref: '#/components/schemas/StatementInitResponseType' + ActionsRSACertificate_inner: + type: object + properties: + type: + type: string + description: Тип действия + example: UPLOAD_ON_TOKEN + available: + type: boolean + description: Признак доступности действия + example: + available: true + type: UPLOAD_ON_TOKEN + _______________________: + title: Причина отказа проверки + type: object + properties: + description: + type: string + description: Текстовое описание причины отказа + example: + description: description + ReceiptAndPayoutList_company: + required: + - accountNumber + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета компании + example: "40702810606050000022" + description: Информация о компании + example: + accountNumber: "40702810606050000022" + ReceiptAndPayoutList_requisite_inner_selfemployed: + required: + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + surname: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Фамилия + example: Иванов + name: + maxLength: 64 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Имя + example: Иван + patronymic: + maxLength: 128 + minLength: 1 + pattern: "^[а-яА-ЯЁё\\-\\s+]*$" + type: string + description: Отчество + example: Иванoвич + description: Персональные данные самозанятого + example: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + ReceiptAndPayoutList_requisite_inner: + required: + - payoutId + - payoutRequisite + - receiptRequisite + - selfemployed + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + selfemployed: + $ref: '#/components/schemas/ReceiptAndPayoutList_requisite_inner_selfemployed' + payoutRequisite: + $ref: '#/components/schemas/PayoutRequisite' + receiptRequisite: + $ref: '#/components/schemas/ReceiptRequisite' + example: + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + PayoutRequisite_byAccount: + required: + - accountNumber + - bic + - purpose + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + bic: + maxLength: 9 + minLength: 9 + pattern: "^([0-9]{9})$" + type: string + description: БИК банка получателя + example: "044525593" + purpose: + maxLength: 210 + minLength: 1 + type: string + description: Назначение платежа + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: + maxLength: 70 + type: string + description: Комментарий к платежу + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + description: Реквизиты для проведения выплаты на счет получателя + example: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + PayoutRequisite_byPan: + required: + - pan + type: object + properties: + pan: + minLength: 1 + type: string + description: Номер карты получателя в зашифрованном виде + example: wS7fElYo8VWeJ8KelaJ0XA== + comment: + maxLength: 70 + type: string + description: Назначение платежа + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + description: Реквизиты для проведения выплаты на карту получателя + example: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + PayoutRequisite_byPhone: + required: + - bankId + - phone + type: object + properties: + phone: + pattern: "^79\\d{9}$" + type: string + description: Телефон + example: "79130000011" + bankId: + maxLength: 12 + minLength: 12 + pattern: "^[0-9]{12}$" + type: string + description: Идентификатор банка получателя + example: "100000000001" + comment: + maxLength: 70 + type: string + description: Комментарий к платежу + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + description: Реквизиты для проведения выплаты по номеру телефона получателя + example: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + ReceiptRequisite_services_inner: + required: + - amount + - name + - quantity + type: object + properties: + amount: + type: string + description: Цена услуги + example: "10.00" + name: + maxLength: 256 + minLength: 1 + type: string + description: Наименование услуги для регистрации дохода + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + quantity: + type: integer + description: Количество услуг. Согласно текущей спецификации ФНС всегда + должно быть равно 1 + default: 1 + description: Список услуг + example: + amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + DigestSignatures_inner: + required: + - base64Encoded + - signatureType + type: object + properties: + base64Encoded: + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + signatureType: + type: string + description: | + Тип электронной подписи + * `RSA` - РСА + * `KEP` - КЭП + example: rsa + enum: + - RSA + - KEP + poaNumber: + type: string + description: Номер машиночитаемой доверенности + example: DOVER_CBR_7702235133_20211102_1 + description: Электронная подпись УЛ Клиента + example: + poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: rsa + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 8658d934-9527-413b-b23c-d87bb1e9824a + ReceiptList_requisite_inner: + required: + - payoutId + - receiptRequisite + - selfemployed + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + selfemployed: + $ref: '#/components/schemas/ReceiptAndPayoutList_requisite_inner_selfemployed' + receiptRequisite: + $ref: '#/components/schemas/ReceiptRequisite' + example: + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + CheckSelfemployedStatusAndPayoutList_company: + required: + - accountNumber + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + description: Информация о компании + example: + accountNumber: "40817810306050000000" + CheckSelfemployedStatusAndPayoutList_requisite_inner: + required: + - payoutId + - payoutRequisite + - selfemployed + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + selfemployed: + $ref: '#/components/schemas/ReceiptAndPayoutList_requisite_inner_selfemployed' + payoutRequisite: + $ref: '#/components/schemas/PayoutRequisite' + example: + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + CheckSelfemployedStatusAndPayoutList_receiptRequisite: + type: object + properties: + receiptId: + type: string + description: Идентификатор чека + example: 200wr5cn4s + example: + receiptId: 200wr5cn4s + PayoutList_requisite_inner: + required: + - payoutId + - payoutRequisite + - selfemployed + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + selfemployed: + $ref: '#/components/schemas/PersonalInformation' + payoutRequisite: + $ref: '#/components/schemas/PayoutRequisite' + example: + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + StatementList_inner_receiptStatus: + required: + - status + - updatedDate + type: object + properties: + status: + $ref: '#/components/schemas/ReceiptStatus' + updatedDate: + type: string + description: Дата и время обновления статуса чека в системе + format: date-time + example: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: IN_PROGRESS + StatementList_inner_payoutStatus: + required: + - status + - updatedDate + type: object + properties: + status: + $ref: '#/components/schemas/PayoutStatus' + updatedDate: + type: string + description: Дата и время обновления статуса выплаты в системе + format: date-time + example: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: READY + StatementList_inner: + required: + - payoutId + - payoutStatus + - receiptStatus + - selfemployed + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + selfemployed: + $ref: '#/components/schemas/PersonalInformation' + payoutRequisite: + $ref: '#/components/schemas/PayoutRequisite' + receiptRequisite: + $ref: '#/components/schemas/ReceiptRequisite' + receiptLink: + $ref: '#/components/schemas/ReceiptLink' + receiptStatus: + $ref: '#/components/schemas/StatementList_inner_receiptStatus' + payoutStatus: + $ref: '#/components/schemas/StatementList_inner_payoutStatus' + errorRecord: + minItems: 0 + type: array + description: Ошибки обработки записей списка + items: + $ref: '#/components/schemas/ErrorRecord_inner' + description: Информация о выплате + example: + receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + selfemployed: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + errorRecord: + - field: field + message: error_description + - field: field + message: error_description + payoutStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: IN_PROGRESS + ErrorRecord_inner: + required: + - message + type: object + properties: + field: + type: string + description: Наменование поля в котором возникла ошибка + example: field + message: + type: string + description: Описание ошибки + example: error_description + example: + field: field + message: error_description + CancelReceiptList_cancelReceipt_inner_receipt_inner: + required: + - cancelReasonCode + - receiptId + type: object + properties: + receiptId: + type: string + description: Идентификатор чека в ФНС + cancelReasonCode: + $ref: '#/components/schemas/CancelReasonCode' + description: Реквизиты аннулируемых чеков + example: + cancelReasonCode: REFUND + receiptId: receiptId + CancelReceiptList_cancelReceipt_inner: + required: + - receipt + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + receipt: + minItems: 1 + type: array + items: + $ref: '#/components/schemas/CancelReceiptList_cancelReceipt_inner_receipt_inner' + example: + vatin: "112233445566" + receipt: + - cancelReasonCode: REFUND + receiptId: receiptId + - cancelReasonCode: REFUND + receiptId: receiptId + PayoutResponse_payoutsList_inner: + type: object + properties: + payoutId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + requestId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + example: 8658d934-9527-413b-b23c-d87bb1e9824a + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + payerAccountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + createdDate: + type: string + description: Дата и время создания запроса в системе + format: date-time + payoutRequisite: + $ref: '#/components/schemas/PayoutRequisite' + receiptRequisite: + $ref: '#/components/schemas/ReceiptRequisite' + receiptLink: + $ref: '#/components/schemas/ReceiptLink' + receiptStatus: + $ref: '#/components/schemas/ReceiptStatus' + payoutStatus: + $ref: '#/components/schemas/PayoutStatus' + example: + receiptLink: + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptId: 200wr5cn4s + payerAccountNumber: "40817810306050000000" + vatin: "112233445566" + createdDate: 2000-01-23T04:56:07.000+00:00 + payoutRequisite: + byPhone: + bankId: "100000000001" + phone: "79130000011" + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutType: ACCOUNT + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810306050000000" + bic: "044525593" + byPan: + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + pan: wS7fElYo8VWeJ8KelaJ0XA== + payoutTotalAmount: "10.00" + receiptRequisite: + receiptTotalAmount: "10.00" + customerVatin: "5566778899" + incomeType: FROM_FOREIGN_AGENCY + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: "10.00" + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + operateDate: 2023-01-18T13:36:42.703Z + customerName: ООО Петуния + requestId: 8658d934-9527-413b-b23c-d87bb1e9824a + externalId: 8658d934-9527-413b-b23c-d87bb1e9824a + payoutStatus: READY + payoutId: 8658d934-9527-413b-b23c-d87bb1e9824a + receiptStatus: IN_PROGRESS + Selfemployed_passport: + description: Паспорт + oneOf: + - $ref: '#/components/schemas/Passport' + - $ref: '#/components/schemas/ForeignPassport' + DigestSignatures_1_inner: + required: + - base64Encoded + - signatureType + type: object + properties: + base64Encoded: + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: + pattern: "([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})" + type: string + signatureType: + type: string + description: | + Тип электронной подписи + * `RSA` - РСА + * `KEP` - КЭП + example: RSA + enum: + - RSA + - KEP + poaNumber: + type: string + description: Номер машиночитаемой доверенности + example: DOVER_CBR_7702235133_20211102_1 + description: Электронная подпись УЛ Клиента + example: + poaNumber: DOVER_CBR_7702235133_20211102_1 + signatureType: RSA + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: certificateUuid + SelfemployedAccount_inner: + required: + - createdDate + - selfemployed + - status + - updatedDate + type: object + properties: + selfemployed: + $ref: '#/components/schemas/Selfemployed' + status: + $ref: '#/components/schemas/SelfEmployedStatus' + updatedDate: + type: string + description: Дата и время обновления статуса самозанятого в системе + format: date-time + createdDate: + type: string + description: Дата и время создания записи о самозанятом в системе + format: date-time + errorRecord: + minItems: 0 + type: array + description: Ошибки обработки записей списка + items: + $ref: '#/components/schemas/ErrorRecord_1_inner' + example: + selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02T00:00:00.000+00:00 + number: "1234567" + dateOfExpiry: 2024-03-02T00:00:00.000+00:00 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02T00:00:00.000+00:00 + email: IvanovIvan@mail.ru + createdDate: 2000-01-23T04:56:07.000+00:00 + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + ErrorRecord_1_inner: + required: + - error_description + type: object + properties: + field: + type: string + description: Наменование поля в котором возникла ошибка + error_description: + type: string + description: Описание ошибки + example: + field: field + error_description: error_description + TaxpayerListStatus_taxpayerStatusList_inner: + required: + - status + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + status: + type: string + description: | + Статус самозанятого в ФНС: + * `TAXPAYER_BOUND` - НП НПД состоит на учете в налоговом органе в качестве НП НПД и передал права банку + * `TAXPAYER_UNBOUND` - НП НПД не привязан к банку-партнеру + * `TAXPAYER_UNREGISTERED` - НП НПД не стоит на учете как самозанятый + enum: + - TAXPAYER_BOUND + - TAXPAYER_UNBOUND + - TAXPAYER_UNREGISTERED + example: + vatin: "112233445566" + status: TAXPAYER_BOUND + AccrualAndDebtListStatus_accrualList_inner_taxChargeList_inner: + required: + - amount + - dueDate + - paidAmount + - updatedAt + type: object + properties: + amount: + type: string + description: Сумма начисления + example: "10.00" + dueDate: + type: string + description: Срок оплаты + format: date + example: 2022-03-02 + paidAmount: + type: string + description: Сумма поступивших оплат в ФНС по данному начислению + example: "10.00" + updatedAt: + type: string + description: Дата и время получения данных из ФНС + format: date-time + example: + amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + AccrualAndDebtListStatus_accrualList_inner_krsbList_inner: + required: + - debt + - overpayment + - penalty + type: object + properties: + debt: + type: number + description: Сумма задолженности + example: 990 + penalty: + type: number + description: Сумма пени + example: 0.1 + overpayment: + type: number + description: Сумма переплаты + example: 0 + updatedAt: + type: string + description: Дата и время получения данных из ФНС + format: date-time + description: Список задолженностей + example: + penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + AccrualAndDebtListStatus_accrualList_inner: + required: + - status + - vatin + type: object + properties: + vatin: + maxLength: 12 + minLength: 12 + pattern: "^([0-9]{12})$" + type: string + description: ИНН самозанятого + example: "112233445566" + status: + type: string + description: | + Статус получения данных из ФНС по самозанятому: + * NEW - Принят для последующей обработки + * SUCCESS - Успешно обработан + * ERROR - Ошибка в процессе обработки + * IN_PROGRESS - В процессе обработки + enum: + - NEW + - SUCCESS + - ERROR + - IN_PROGRESS + ftsError: + type: string + description: Ошибка ФНС + taxChargeList: + minItems: 0 + type: array + description: Список налоговых начислений + items: + $ref: '#/components/schemas/AccrualAndDebtListStatus_accrualList_inner_taxChargeList_inner' + krsbList: + minItems: 0 + type: array + items: + $ref: '#/components/schemas/AccrualAndDebtListStatus_accrualList_inner_krsbList_inner' + example: + vatin: "112233445566" + ftsError: ftsError + taxChargeList: + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + - amount: "10.00" + dueDate: 2022-03-02T00:00:00.000+00:00 + paidAmount: "10.00" + updatedAt: 2000-01-23T04:56:07.000+00:00 + krsbList: + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + - penalty: 0.1 + overpayment: 0 + debt: 990 + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: NEW + ReceiptV2_services_inner: + type: object + properties: + amount: + type: number + description: Цена услуги + example: 10.05 + name: + type: string + description: Наименование услуги для регистрации дохода + example: Курьерские услуги за период с 1.12.2020-20.12.2020 + quantity: + type: integer + description: Количество + example: + amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + Activities_inner: + required: + - id + - name + type: object + properties: + id: + maxLength: 5 + minLength: 1 + type: string + description: Идентификатор вида деятельности + example: "17" + name: + maxLength: 128 + minLength: 1 + type: string + description: Наименование вида деятельности + example: Доставка + example: + name: Доставка + id: "17" + Regions_inner: + required: + - name + - oktmo + type: object + properties: + oktmo: + maxLength: 8 + minLength: 8 + type: string + description: ОКТМО региона ведения деятельности + example: "40000000" + name: + maxLength: 128 + minLength: 1 + type: string + description: Наименование региона ведения деятельности + example: Санкт-Петербург + example: + oktmo: "40000000" + name: Санкт-Петербург + SbpBanks_inner: + required: + - bankId + - bankName + type: object + properties: + bankName: + type: string + example: Газпромбанк + bankId: + maxLength: 12 + minLength: 12 + pattern: "^[0-9]{12}$" + type: string + example: "100000000001" + example: + bankId: "100000000001" + bankName: Газпромбанк + GetAccounts_inner: + required: + - accountNumber + - isActive + type: object + properties: + accountNumber: + maxLength: 20 + minLength: 20 + pattern: "^([0-9]{20})$" + type: string + description: Номер счета + example: "40817810306050000000" + isActive: + type: boolean + description: | + Признак активности номинального счета: + * `true` - Активен; + * `false` - Деактивирован. + description: Ответ на запрос получения списка номинальных счетов + example: + accountNumber: "40817810306050000000" + isActive: true + DigestSignatures_2_inner: + required: + - base64Encoded + - signatureType + type: object + properties: + base64Encoded: + type: string + description: "Значение электронной подписи, закодированное в Base64" + example: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: + description: "Идентификатор сертификата, использованного при создании ЭП" + allOf: + - $ref: '#/components/schemas/UUID_2' + signatureType: + type: string + description: | + Тип электронной подписи + * `rsa` - РСА + * `kep` - КЭП + example: rsa + enum: + - rsa + - kep + poaNumber: + type: string + description: Номер машиночитаемой доверенности + example: DOVER_CBR_7702235133_20211102_1 + description: Электронная подпись УЛ Клиента + Report_type: + required: + - code + - title + type: object + properties: + code: + type: string + description: Код типа документа + title: + type: string + description: Название документа + description: + type: string + description: Описание назначения документа + description: Информация о типе справки/выписки + example: + code: code + description: description + title: title + Report_status: + required: + - code + - title + type: object + properties: + code: + type: string + description: Идентификатор статуса + enum: + - NEW + - ENQUEUED + - ENQUEUED_POST_PROCESS + - PENDING + - STARTED + - FINISHED + - REJECTED + - LOADED + - LOADED_SIGNED + - ERROR + - REVISION + title: + type: string + description: Описание статуса + description: Статус заказанного документа + example: + code: NEW + title: title + UserLimit_allOf: + required: + - countriesRestrictions + - created + - id + type: object + properties: + id: + type: integer + created: + type: string + format: date + countriesRestrictions: + $ref: '#/components/schemas/CountriesRestrictions' + Offices_cardAttributes: + required: + - anyOfficeUnnamedEnabled + - namedCardEnabled + - unnamedCardEnabled + type: object + properties: + unnamedCardEnabled: + type: boolean + description: Признак доступности неименной карты + example: true + namedCardEnabled: + type: boolean + description: Признак доступности именной карты + example: false + anyOfficeUnnamedEnabled: + type: boolean + description: Признак доступности получения неименной карты в любом офисе + example: false + description: Атрибуты карты и ее доступности + example: + namedCardEnabled: false + unnamedCardEnabled: true + anyOfficeUnnamedEnabled: false + GetAccountsResponse_Data: + type: object + properties: + Account: + type: array + items: + $ref: '#/components/schemas/Account_3' + example: + Account: + - accountId: accountId + Owner: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Servicer: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + accountDescription: accountDescription + accountType: null + currency: currency + status: null + AccountDetails: + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - accountId: accountId + Owner: + cityOfBirth: cityOfBirth + identification: + identification: identification + schemeName: RU.CBR.TXID + postalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + mobileNumber: mobileNumber + name: name + countryOfResidence: countryOfResidence + birthDate: birthDate + Servicer: + PostalAddress: + country: country + streetName: streetName + townName: townName + countrySubDivision: countrySubDivision + addressType: null + buildingNumber: buildingNumber + postCode: postCode + addressLine: + - addressLine + - addressLine + OrganizationIdentification: + - identification: identification + schemeName: RU.CBR.TXID + - identification: identification + schemeName: RU.CBR.TXID + name: name + BankIdentification: + - identification: identification + schemeName: RU.CBR.BICFI + - identification: identification + schemeName: RU.CBR.BICFI + CorrespondentAccount: + identification: identification + schemeName: RU.CBR.BBAN + accountDescription: accountDescription + accountType: null + currency: currency + status: null + AccountDetails: + - identification: identification + name: name + schemeName: RU.CBR.BBAN + - identification: identification + name: name + schemeName: RU.CBR.BBAN + BalanceResponse_1_Data: + description: Полезная нагрузка ответа + allOf: + - $ref: '#/components/schemas/DataBalanceResponse' + BalanceResponse_1_Meta: + description: Раздел метаданных + allOf: + - $ref: '#/components/schemas/Meta_1' + Balance_Amount: + description: Сумма остатка + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount_1' + OBRUCreditLine_Amount: + description: Значение лимита внутридневного кредитования (ВДК) + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount_1' + TransactionResponse_Data: + description: Полезная нагрузка ответа на запрос об операциях по счету + allOf: + - $ref: '#/components/schemas/DataTransactionResponse' + TransactionHistory_Amount: + description: Информация о сумме и валюте операции по счету + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount_2' + TransactionHistory_BankTransactionCode: + description: Подробная информация для полной идентификации собственного банковского + кода операции по счету + example: + code: Payments + subCode: MerchantCardTransactions + allOf: + - $ref: '#/components/schemas/BankTransactionCode' + TransactionHistory_ChargeAmount: + description: Комиссия за операциию по счету + example: + amount: "2.00" + currency: RUB + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount_2' + TransactionHistory_InstructedAmount: + description: "Сумма денег, подлежащая переводу между плательщиком и получате\ + лем денежных средств до вычета расходов, выраженная в валюте обозначенной\ + \ инициирующей стороной" + example: + amount: "202.00" + currency: RUB + allOf: + - $ref: '#/components/schemas/ActiveOrHistoricCurrencyAndAmount_2' + TransactionHistory_Debtor_PostalAddress: + type: object + properties: + townName: + maxLength: 35 + minLength: 1 + pattern: "^[\\w\\W]{1,35}$" + type: string + description: "Наименование населённого пункта или территории, находящейс\ + я вне границ поселений" + example: Бигсити + country: + pattern: "^[A-Z]{3,3}$" + type: string + description: Код страны в формате ISO 3166-1 alpha-3 + example: RUS + additionalProperties: false + description: Почтовый адрес + TransactionHistory_Debtor: + required: + - name + type: object + properties: + name: + maxLength: 160 + minLength: 1 + pattern: "^[\\w\\W]{1,160}$" + type: string + description: Наименование организации или имя физического лица + example: Наименование организации или физического лица + Identification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация юридического или физического лица. + items: + $ref: '#/components/schemas/IdentificationType' + MerchantInformation: + $ref: '#/components/schemas/MerchantInfo' + PostalAddress: + $ref: '#/components/schemas/TransactionHistory_Debtor_PostalAddress' + additionalProperties: false + description: Плательщик + TransactionHistory_DebtorAccount: + description: "Уникальная идентификация счета плательщика, на котором будет с\ + делана дебетовая запись в результате операции" + example: + name: Моя карта + schemeName: RU.CBR.PAN + identification: '**1234' + allOf: + - $ref: '#/components/schemas/CashAccount' + TransactionHistory_CreditorAccount: + description: | + Идентификатор счета получателя средств, на котором будет проведена запись + о кредите в результате операции. + Применение: должен быть указан, если значение параметра `creditDebitIndicator` равно `debit` + allOf: + - $ref: '#/components/schemas/CashAccount' + TransactionHistory_Creditor: + required: + - name + type: object + properties: + name: + maxLength: 160 + minLength: 1 + pattern: "^[\\w\\W]{1,160}$" + type: string + description: Наименование организации или имя физического лица + example: Наименование организации или физического лица + Identification: + maxItems: 12 + minItems: 1 + type: array + description: Идентификация юридического или физического лица. + items: + $ref: '#/components/schemas/IdentificationType' + MerchantInformation: + $ref: '#/components/schemas/MerchantInfo' + PostalAddress: + $ref: '#/components/schemas/TransactionHistory_Debtor_PostalAddress' + additionalProperties: false + description: Получатель денежных средств + example: + name: Пятерочка + Identification: + - schemeName: RU.CBR.BBAN + identification: "6574836428347453" + PostalAddress: + townName: Бигсити + country: RUS + MerchantInformation: + merchantId: 19427360OFALLONMO + merchantCategoryCode: "1234" + TransactionHistory_CardTransaction: + description: "Предоставляет данные по карте (номер, платежная система), терм\ + иналу (номер, идентификатор) и транзакционные данные, используемые для уни\ + кальной идентификации операции по карте Объект `Transaction.CardTransaction`\ + \ не должен возвращаться, если нет отсутствует разрешение `ReadPaymentCards`" + allOf: + - $ref: '#/components/schemas/CardTransaction' + TransactionHistory_RemittanceInformation: + required: + - unstructured + type: object + properties: + unstructured: + maxLength: 140 + minLength: 1 + pattern: "^[\\w\\W]{1,140}$" + type: string + description: Текстовое назначение платежа + example: Назначение платежа - оплата за товары или услуги + additionalProperties: false + description: "Предоставляемая информация, позволяющая сопоставить запись с п\ + озициями, для которых предназначен перевод, такими как коммерческие счета\ + \ в системе дебиторской задолженности" + CardTransaction_Transaction: + description: "Сведения об отдельной операции по карте, записанные на POI-тер\ + минале (точке взаимодействия)" + allOf: + - $ref: '#/components/schemas/CardIndividualTransaction' + AccountPaymentCardsResponse_Data_PaymentCard_inner: + type: object + allOf: + - $ref: '#/components/schemas/AccountPaymentCardsData' + AccountPaymentCardsResponse_Data: + type: object + properties: + PaymentCard: + maxItems: 50 + minItems: 0 + type: array + items: + $ref: '#/components/schemas/AccountPaymentCardsResponse_Data_PaymentCard_inner' + description: Раздел данных + example: + PaymentCard: + - null + - null + - null + - null + - null + PhonePaymentReport_orderInfo: + type: object + properties: + number: + type: string + description: Номер платежного поручения + date: + type: string + description: Дата платежного поручения + format: date-time + recipientAccount: + type: string + description: расчетный счет ФЛ в банке-получателе + recipientBic: + type: string + description: БИК банка-получателя + example: + date: 2000-01-23T04:56:07.000+00:00 + number: number + recipientAccount: recipientAccount + recipientBic: recipientBic + CardInfoRequest_embossedText: + required: + - firstName + - lastName + type: object + properties: + firstName: + type: string + description: Эмбоссированнное имя + lastName: + type: string + description: Эмбоссированнная фамилия + salutation: + type: string + description: Эмбоссированнное обращение + example: + firstName: firstName + lastName: lastName + salutation: salutation + CreatePayrollApplicationResponse_originalMessage: + required: + - createdAt + - id + - status + type: object + properties: + id: + type: string + description: Уникальный id исходного сообщения с ведомостью + createdAt: + type: string + description: Дата и время формирования исходного сообщения с ведомостью4 + format: date-time + status: + type: string + description: Статус исходного сообщения + reason: + type: string + description: Описание причины присвоения статуса сообщения + example: + createdAt: 2000-01-23T04:56:07.000+00:00 + reason: reason + id: id + status: status + CreatePayrollApplicationResponse_payroll_accrual: + required: + - id + - status + - updatedAt + type: object + properties: + id: + type: string + description: Номер начисления в ведомости + updatedAt: + type: string + description: Дата и время присвоения статуса + format: date-time + status: + type: string + description: Статус начисления + reason: + type: string + description: Описание кода причины присвоения статуса начисления + example: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + CreatePayrollApplicationResponse_payroll: + required: + - id + - status + type: object + properties: + id: + type: string + description: Идентификатор исходного пакета с ведомостью + status: + type: string + description: Статус исходного пакета с ведомостью + reason: + type: string + description: Описание причины присвоения статуса пакета с ведомостью + accrual: + $ref: '#/components/schemas/CreatePayrollApplicationResponse_payroll_accrual' + example: + reason: reason + id: id + accrual: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + status: status + GetPayrollApplicationResponse_payroll_accrual: + required: + - id + - status + type: object + properties: + id: + type: string + description: Номер начисления в ведомости + updatedAt: + type: string + description: Дата и время присвоения статуса + format: date-time + status: + type: string + description: Статус начисления + reason: + type: string + description: Описание кода причины присвоения статуса начисления + example: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + GetPayrollApplicationResponse_payroll: + required: + - id + - status + type: object + properties: + id: + type: string + description: Идентификатор исходного пакета с ведомостью + status: + type: string + description: Статус исходного пакета с ведомостью + reason: + type: string + description: Описание причины присвоения статуса пакета с ведомостью + accrual: + $ref: '#/components/schemas/GetPayrollApplicationResponse_payroll_accrual' + example: + reason: reason + id: id + accrual: + reason: reason + id: id + updatedAt: 2000-01-23T04:56:07.000+00:00 + status: status + status: status + ResponseCertificates_inner: + required: + - algorithm + - beginDateTime + - clientId + - expireDateTime + - fingerprint + - id + - ownerName + - serialNumber + - type + type: object + properties: + id: + type: string + example: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + clientId: + type: string + example: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + ownerName: + type: string + example: Иванов Иван Иванович + fingerprint: + type: string + example: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + organizationName: + type: string + nullable: true + example: ООО 'Ромашка' + beginDateTime: + type: string + format: date-time + example: 2023-07-28T15:11:14Z + expireDateTime: + type: string + format: date-time + example: 2025-06-19T11:48:06Z + status: + type: string + example: ACTIVE + enum: + - ACTIVE + - REVOKED + - DELETED + certificateBody: + type: string + example: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: + type: string + example: ENCRYPTION + enum: + - ENCRYPTION + - SIGNATURE + - TLS + algorithm: + type: string + example: RS256 + enum: + - RS256 + - GOST + serialNumber: + type: string + example: "2163173489423972678179275487230070851350268586" + example: + expireDateTime: 2025-06-19T11:48:06Z + clientId: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + serialNumber: "2163173489423972678179275487230070851350268586" + ownerName: Иванов Иван Иванович + organizationName: ООО 'Ромашка' + fingerprint: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + id: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + beginDateTime: 2023-07-28T15:11:14Z + type: ENCRYPTION + status: ACTIVE + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + algorithm: RS256 + CreateIndividualRequest_city: + required: + - cityId + - presenceCityTitle + - regionId + type: object + properties: + cityId: + type: integer + description: Идентификатор города. + regionId: + type: integer + description: Идентификатор региона. + presenceCityTitle: + type: string + description: Отображаемое наименование города присутствия. + description: Город присутствия банка и регион регистрации. + example: + regionId: 6 + cityId: 0 + presenceCityTitle: presenceCityTitle + IndividualLead_city: + required: + - cityId + - presenceCityTitle + - regionId + type: object + properties: + cityId: + type: integer + example: 1 + regionId: + type: integer + example: 77 + presenceCityTitle: + type: string + example: Москва + example: + regionId: 77 + cityId: 1 + presenceCityTitle: Москва + ComplianceScoreResponse_boundaries: + type: object + properties: + low: + type: number + description: Граница между низким и средним уровнем риска + format: float + example: 0.32 + high: + type: number + description: Граница между средним и высоким уровнем риска + format: float + example: 0.65 + example: + high: 0.65 + low: 0.32 + responses: + "200GetAccounts": + description: "Полный список счетов (с идентификаторами accountId), которые б\ + ыли авторизованы Пользователем на стороне ППИУ" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/AccountResponse' + "400Error-req": + description: "Запрос имеет неверное, отсутствующее или несовместимое тело JSON,\ + \ параметры URL или поля заголовка" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "400" + id: 4aca5b0d-1730-416f-a52b-6d353b687082 + message: Bad Request + Errors: + - errorCode: RU.CBR.Field.Missing + message: "Обязательное поле, необходимое для API, отсутствует в поле\ + зной нагрузке" + path: Data.Model.Object.filled + url: https://example.com/error-description + "401Error-req": + description: Заголовок авторизации отсутствует или неверный токен + headers: + x-fapi-interaction-id: + required: true + schema: + type: string + format: uuid + www-authenticate: + required: true + schema: + type: string + enum: + - Valid token required + "403Error-req": + description: Токен имеет неверную область действия или была нарушена политика + безопасности + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "403" + id: ab41a751-619b-4947-bf0a-251f6e92f599 + message: Forbidden + Errors: + - errorCode: RU.CBR.Authenticate.InvalidScope + message: Предъявленный токен доступа не содержит область действия (scope) + необходимый для доступа к ресурсу + url: https://example.com/error-description + "405Error-req": + description: "Сторонний Поставщик пытается получить доступ к ресурсу с помощ\ + ью метода, который не поддерживается" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "406Error-req": + description: "Запрос содержал параметр заголовка Accept, отличный от разреше\ + нных media types, и набор символов, отличный от UTF-8" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + "429Error-req": + description: "Операция была отклонена, так как слишком много запросов было с\ + делано в течение определенного периода времени" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + Retry-After: + schema: + type: string + "500Error-req": + description: Что-то пошло не так на стороне Стороннего поставщика. + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "500" + id: af467d1b-985d-4a8e-972e-24a32287085f + message: Internal Server Error + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Что-то пошло не так на стороне Поставщика услуг + path: Data.Model.Object.filled + url: https://example.com/error-description + "501Error-req": + description: "Сторонний поставщик не поддерживает функции, необходимые для в\ + ыполнения запроса" + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "501" + id: 451f7718-2e96-46f0-b286-4b1c8370b87e + message: Not Implemented + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Данный код ошибки можно использовать при возникновении непредвиденной + ошибки + path: Data.Model.Object.filled + url: https://example.com/error-description + "503Error-req": + description: Сервис временно не доступен + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse' + example: + code: "503" + id: 63a8dddb-b92d-4ac7-82c3-c9a9efb878a5 + message: Service Unavailable + Errors: + - errorCode: RU.CBR.UnexpectedError + message: Сервис временно не доступен + path: Data.Model.Object.filled + url: https://example.com/error-description + "200GetAccountsaccountIdStatementsStatementId": + description: Ответ получения выписки по идентификатору выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + content: + application/json: + schema: + $ref: '#/components/schemas/StatementResponse' + "201PostStatementInitResponse": + description: Индентификатор выписки + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора коррел\ + яции. Если необходимо, то Сторонний поставщик передает обратно значени\ + е идентификатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + format: uuid + x-jws-signature: + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + content: + application/json: + schema: + $ref: '#/components/schemas/StatementInitResponse' + example: + Data: + Statement: + statementId: this-is-a-slug-format-statement-id + accountId: this-is-a-slug-format-account-id + fromBookingDateTime: 2019-09-15T00:00:00+00:00 + toBookingDateTime: 2019-12-15T00:00:00+00:00 + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + "404Error-req": + description: Endpoint is not found or not active + headers: + x-fapi-interaction-id: + $ref: '#/components/headers/x-fapi-interaction-id' + content: + application/json: + schema: + $ref: '#/components/schemas/OBRUErrorResponse_1' + example: + code: "404" + message: Not found + Errors: + - errorCode: RU.CBR.Resource.NotFound + message: Endpoint is not found or not active + parameters: + x-fapi-interaction-id: + name: x-fapi-interaction-id + in: header + description: "RFC4122 UID, используемый в качестве идентификатора корреляции\ + . Если необходимо, то Сторонний поставщик передает обратно значение иденти\ + фикатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в со\ + ответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID) URN Namespace\"\ + ." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + page: + name: page + in: query + description: Номер страницы + required: false + schema: + maximum: 5000 + minimum: 1 + type: integer + format: int32 + default: 1 + x-fapi-auth-date: + name: x-fapi-auth-date + in: header + description: "Время последнего входа Пользователя в систему с TPP. Значение\ + \ предоставляется в виде HTTP-date, как в разделе 7.1.1.1 [RFC7231]. Напри\ + мер, x-fapi-auth-date: Mon, 26 Aug 2019 12:23:11 GMT" + required: false + schema: + maxLength: 29 + minLength: 1 + pattern: "^[a-zA-Z0-9 :,]{29}$" + type: string + example: "Mon, 26 Aug 2019 12:23:11 GMT" + x-fapi-customer-ip-address: + name: x-fapi-customer-ip-address + in: header + description: "IP-адрес Пользователя, если Пользователь в данный момент подкл\ + ючен к Стороннему Поставщику (авторизован в приложении Стороннего Поставщи\ + ка)." + required: false + schema: + maxLength: 21 + minLength: 0 + pattern: "^([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}|(\\d{1,3}\\.){3}\\d{1,3}$" + type: string + example: 172.123.123.123 + x-customer-user-agent: + name: x-customer-user-agent + in: header + description: "В заголовке указывается тип устройства (user-agent), который и\ + спользует Пользователь. Сторонний Поставщик может заполнить это поле значе\ + нием типа устройства (user-agent), указанным Пользователем. Если Пользоват\ + ель использует мобильное приложение Стороннего Поставщика, Сторонний Поста\ + вщик проверяет, что строка типа устройства (user-agent) отличается от стро\ + ки типа устройства (user-agent) на основе браузера." + required: false + schema: + type: string + example: mobile + accountId: + name: accountId + in: path + description: Идентификатор счета + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: this-is-a-slug-format-account-id + fromBookingDateTime: + name: fromBookingDateTime + in: query + description: Дата и время начала фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + toBookingDateTime: + name: toBookingDateTime + in: query + description: Дата и время окончания фильтрации списка операций по счету + required: false + schema: + type: string + description: Формат даты и времени + format: date-time-string + example: 2021-06-05T15:15:13+00:00 + x-idempotency-key: + name: x-idempotency-key + in: header + description: Уникальный идентификатор запроса для поддержки идемпотентности. + Обязательно для запросов POST к конечным точкам идемпотентного ресурса. Для + других запросов не указывается. + required: true + schema: + type: string + format: uuid + x-jws-signature: + name: x-jws-signature + in: header + description: Отделяемая подпись полезной нагрузки в формате JWS + required: true + schema: + type: string + statementId: + name: statementId + in: path + description: Идентификатор выписки + required: true + schema: + maxLength: 40 + minLength: 1 + pattern: "^[a-zA-Z0-9-]{1,40}$" + type: string + example: 9b23e27e-f4f8-4cab-9b80-aaa008d4330c + accountNumber: + name: accountNumber + in: path + description: Номер счета + required: true + schema: + type: string + cardFilter: + name: cardFilter + in: query + description: Фильтр карт + required: false + cardId: + name: cardId + in: path + description: Идентификатор пластиковой карты + required: true + schema: + type: string + DateFrom: + name: dateFrom + in: query + description: Дата начала запроса истории операций (включительно) + required: false + schema: + type: string + format: date + DateTo: + name: dateTo + in: query + description: Дата окончания запроса истории операций (включительно) + required: false + schema: + type: string + format: date + Accounts: + name: accounts + in: query + description: Массив номеров счетов для выборки истории операций + required: false + schema: + type: array + items: + type: string + description: Номер счёта + Cards: + name: cards + in: query + description: Массив идентификаторов пластиковых карт для выборки истории операций + required: false + schema: + type: array + items: + type: string + description: Идентификатор пластиковой карты + OperationDirection: + name: operationDirection + in: query + description: "Направление движения денежных средств: INCOME - приход/пополне\ + ние, EXPENSE - расход/списание" + required: false + schema: + type: string + enum: + - EXPENSE + - INCOME + Offset: + name: offset + in: query + description: Параметр пагинации - Смещение от начала + required: false + schema: + type: integer + Limit: + name: limit + in: query + description: Параметр пагинации - Запрашиваемое кол-во элементов на странице + required: false + schema: + type: integer + operationId: + name: id + in: path + description: Идентификатор операции + required: true + schema: + type: string + limitId: + name: limitId + in: path + description: Идентификатор пользовательского лимита + required: true + schema: + type: integer + formId: + name: formId + in: path + description: Идентификатор заявки + required: true + schema: + type: string + example: 55A42D1698400C9EE0543863BB4C2866 + phase: + name: phase + in: query + description: Этап процесса оформления заявки + required: true + schema: + $ref: '#/components/schemas/PhaseId' + accuracy: + name: accuracy + in: query + description: Точность определения координат + required: true + schema: + type: integer + example: 5 + address: + name: address + in: query + description: "Адрес, в радиусе которого ведется поиск" + required: true + schema: + type: string + example: "г. Москва, ул. Анохина, д. 9" + kladrId: + name: kladrId + in: query + description: КЛАДР города доставки + required: true + schema: + type: string + example: "7700000000000" + latitude: + name: latitude + in: query + description: Широта + required: true + schema: + type: number + example: 55.659348 + longitude: + name: longitude + in: query + description: Долгота + required: true + schema: + type: number + example: 37.472997 + radius: + name: radius + in: query + description: "Радиус поиска относительно указанных координат, м." + required: false + schema: + type: number + example: 3000 + isUnnamed: + name: isUnnamed + in: query + description: Признак неименной/именной карты + required: true + schema: + type: boolean + example: true + cityId: + name: cityId + in: query + description: Код города доставки + required: true + schema: + type: string + example: "21" + b2bClientId: + name: b2bClientId + in: query + description: "Идентификатор клиента, от имени которого выполняется запрос" + required: true + schema: + type: string + format: uuid + example: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + qrcId: + name: qrcId + in: query + description: Идентификатор платежной ссылки + required: false + schema: + maxLength: 32 + minLength: 1 + type: string + example: AO1000670LSS7DN18SJQDNP4B05KLJL2 + limit: + name: limit + in: query + description: Количество элементов + required: false + schema: + maximum: 100 + minimum: 1 + type: integer + example: 10 + offset: + name: offset + in: query + description: Смещение в результатах поиска + required: false + schema: + minimum: 0 + type: integer + example: 0 + merchantId: + name: merchantId + in: path + required: true + schema: + type: string + example: MF0000000001 + authToken: + name: Authorization-1C + in: header + description: Basic auth логин и пароль клиента в формате base64(login:password) + required: true + schema: + type: string + example: Basic NWUfYlNaUkR6dUpGc3JtGTtULkJVOk3eNmlwTWRLdk8yUg== + qrId: + name: qrId + in: path + required: true + schema: + type: string + example: EX2E009997EAL2DG8VFAEN07M1VH92DW + b2cClientId: + name: b2cClientId + in: query + description: "Идентификатор клиента, от имени которого интегратором отправля\ + ется платеж" + schema: + type: string + partnerId: + name: partnerId + in: query + description: Идентификатор партнера + required: true + schema: + type: integer + format: int64 + startDate: + name: startDate + in: query + description: Дата начала периода + schema: + type: string + format: date-time + finishDate: + name: finishDate + in: query + description: Дата окончания периода + schema: + type: string + format: date-time + transactionId: + name: transactionId + in: query + description: Идентификатор транзакции + schema: + type: string + packageId: + name: packageId + in: path + description: Идентификатор пакета платежей + required: true + schema: + type: integer + format: int64 + checkId: + name: checkId + in: path + description: Идентификатор асинхронного запроса на проверку возможности платежа + required: true + schema: + type: string + inn: + name: inn + in: query + description: ИНН ЮЛ + required: true + schema: + type: string + active: + name: active + in: query + description: Признак возврата активных подписок + required: false + schema: + type: boolean + default: true + example: true + sort: + name: sort + in: query + description: "Порядок сортировки в формате <имя_поля,asc|desc>. Допустимо ук\ + азать несколько значений" + required: false + schema: + type: array + items: + type: string + example: + - "dfaName,desc" + customerType: + name: customerType + in: query + description: | + Тип инвестора. Возможные значения: + * `PERSON` - физическое лицо; + * `COMPANY` - юридическое лицо + required: false + schema: + type: string + example: PERSON + dfaName: + name: dfaName + in: query + description: Параметр фильтрации по наименованию ЦФА + required: false + schema: + type: string + example: NRD-DT-080324-0100 + dfaRedemptionDate: + name: dfaRedemptionDate + in: query + description: Параметр фильтрации по дате погашения ЦФА + required: false + schema: + type: string + format: date + example: 2024-04-30 + dfaParValue: + name: dfaParValue + in: query + description: Параметр фильтрации по стоимости ЦФА + required: false + schema: + type: integer + format: int64 + example: 100000 + dfaType: + name: dfaType + in: query + description: Параметр фильтрации по типу ЦФА + required: false + schema: + type: string + example: MONEY_CLAIM + dfaRateAmount: + name: dfaRateAmount + in: query + description: Параметр фильтрации по процентной ставке ЦФА + required: false + schema: + type: string + example: "1" + companyIssuerName: + name: companyIssuerName + in: query + description: Параметр фильтрации по наименованию эмитента + required: false + schema: + type: string + example: Акционерное общество "Альфа банк" + claimId: + name: claimId + in: path + description: Идентификатор обращения в Банке + required: true + schema: + type: string + example: A2504090003 + orderId: + name: orderId + in: path + description: Идентификатор заказа в банке + required: true + schema: + type: string + example: s-5555 + FromDate: + name: fromDate + in: query + description: Начало интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-01T00:00:00.001Z + ToDate: + name: toDate + in: query + description: Конец интервала (ISO 8601 с миллисекундами и Z) + required: false + schema: + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" + type: string + format: date-time + example: 2025-08-31T23:59:59.999Z + Sort: + name: sort + in: query + description: "Сортировка по полю и направлению. Формат: поле,направление. До\ + ступные поля: createdAt, updatedAt. Доступные направления: asc (по возраст\ + анию), desc (по убыванию)." + required: false + schema: + pattern: "^(createdAt|updatedAt),(asc|desc)$" + type: string + example: "createdAt,asc" + individualId: + name: individualId + in: path + required: true + schema: + type: string + llcId: + name: llcId + in: path + required: true + schema: + type: string + month: + name: month + in: query + description: Отчётный месяц (ISO 8601). Не старше 6 месяцев от текущей даты. + required: true + style: form + explode: false + schema: + $ref: '#/components/schemas/MonthPeriod' + example: 2025-08-01T00:00:00.000Z + productCode: + name: productCode + in: query + description: Код продукта. Допускается передача только одного значения. + required: true + style: form + explode: false + schema: + type: string + example: DEBIT_CARD + examples: + getCustomerInfo: + summary: Пример ответа + value: + ogrn: "1020203094163" + organizationForm: + code: "12300" + fullName: Общество с ограниченной ответственностью + shortName: ООО + type: "2014" + address: + area: Тахтамукайский район + settlementType: г. + zip: "385600" + country: "643" + fiasCode: 046b6c7f-0b8a-43b9-b35d-6489e6daee91 + city: Майкоп + house: "3" + building: "1" + settlement: Майкоп + flat: "123" + street: улица Депутатская + fullAddress: "Республика Адыгея, г. Майкоп, улица Депутатская, д. 3" + region: Республика Адыгея + inn: "114693784" + fullName: Общество с ограниченной ответственностью "Ромашка" + type: LEGAL + okpo: "41294456" + organizationId: bca96ae8b26184217fcf75f51347bd7bd5031ea6605c434c49f85378e9509732 + phone: "79099876543" + okved: "71.12" + registrationDate: 2000-01-23T04:56:07.000+00:00 + kpps: + - "2427920" + - "2427920" + accounts: + - specConditions: + - code: AI17 + description: Счёт заблокирован + value: true + - code: AI17 + description: Счёт заблокирован + value: true + clientName: Наименование + typeName: Расчётный счёт + type: PAYMENT + amountOverdraftOwnFunds: 0.8008281904610115 + amountOverdraftLimit: 100000 + amountBalance: 810000 + amountHolds: 100 + number: "40702810002300001935" + blockedSums: + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + bank: + bic: "044525593" + transitAccountNumber: "40702978904100000001" + amountTotal: 100000 + openDate: 2021-10-07 + currencyCode: "810" + - specConditions: + - code: AI17 + description: Счёт заблокирован + value: true + - code: AI17 + description: Счёт заблокирован + value: true + clientName: Наименование + typeName: Расчётный счёт + type: PAYMENT + amountOverdraftOwnFunds: 0.8008281904610115 + amountOverdraftLimit: 100000 + amountBalance: 810000 + amountHolds: 100 + number: "40702810002300001935" + blockedSums: + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + - beginDate: 2020-10-23 + num: "112233" + initiator: Межрайонная ИФНС России № 51 по г. Москве + blockType: PARTIAL_BALANCE_BLOCK + cause: "Неисполнение требования об уплате налога, сбора, пени, штрафа\ + \ № 53228 от 05.11.2019 г" + sum: "988800" + bank: + bic: "044525593" + transitAccountNumber: "40702978904100000001" + amountTotal: 100000 + openDate: 2021-10-07 + currencyCode: "810" + shortName: ООО "Ромашка" + category: BANK + email: client@example.com + status: ACTIVE + Response: + summary: Пример ответа + value: | + + + + 100 + 0 + 10 + + + + 40702810102300000001 + + 044525593 + 30101810200000000593 + АО "АЛЬФА-БАНК" г Москва + + 1000.00 + 2022-06-27T00:00:00.000 + 2022-06-27T23:59:59.999 + 1000.00 + + 2022-06-27 + 1 + + + + 18810630012040000120 + 17.02.2022 + 0 + 01 + 45348000 + 0 + 17.02.2022 + + 18810192111439342569 + 2022-06-27 + 24 + + 03100643000000019500 + + 024501901 + 40102810045370000002 + ОПЕРАЦИОННЫЙ ДЕПАРТАМЕНТ БАНКА РОССИИ//Межрегиональное операционное УФК г Москва + + 1901108410 + 191043001 + УГИБДД ГУ МВД России по г. Москве + + + 40702810102300000001 + + 044525593 + 30101810200000000593 + АО "АЛЬФА-БАНК" г Москва + + 0665413230 + 011206020 + Общество с ограниченной ответственностью "Ромашка" + + почтой + 5 + Штраф ГИБДД + 10.00 + 01 + + + + 044525593 + 30101810200000000593 + АО "АЛЬФА-БАНК" г Москва + + 02 + Исполнен + + + + + 044525593 + 30101810200000000593 + АО "АЛЬФА-БАНК" г Москва + + 0 + 80.00 + 80.00 + + + + + + ResponseSigned: + summary: Пример подписанного ответа + value: "\n\n\t\n\t\t100\n\ + \t\t0\n\t\t10\n\t\n\ + \t\n\t\t\n\t\t\t40702810102300000001\n\ + \t\t\t\n\t\t\t\t044525593\n\t\t\t\t30101810200000000593\n\ + \t\t\t\tАО \"АЛЬФА-БАНК\" г Москва\n\t\t\t\n\t\t\t1000.00\n\ + \t\t\t2022-06-27T00:00:00.000\n\t\t\t2022-06-27T23:59:59.999\n\ + \t\t\t1000.00\n\t\t\t\n\t\t\ + \t\t2022-06-27\n\t\t\t\t1\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t18810630012040000120\n\t\t\t\t\t\t\t17.02.2022\n\ + \t\t\t\t\t\t\t0\n\t\t\t\t\t\t\t01\n\ + \t\t\t\t\t\t\t45348000\n\t\t\t\t\t\t\t0\n\t\ + \t\t\t\t\t\t17.02.2022\n\t\t\t\t\t\t\n\ + \t\t\t\t\t\t18810192111439342569\n\t\t\t\t\t\t2022-06-27\n\ + \t\t\t\t\t\t24\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t03100643000000019500\n\ + \t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t024501901\n\t\t\t\t\t\t\t\ + \t40102810045370000002\n\t\t\t\t\t\t\t\tОПЕ\ + РАЦИОННЫЙ ДЕПАРТАМЕНТ БАНКА РОССИИ//Межрегиональное операционное УФК г Мос\ + ква\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t1901108410\n\t\ + \t\t\t\t\t\t191043001\n\t\t\t\t\t\t\tУГИБДД ГУ МВД России\ + \ по г. Москве\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\ + \t\t\t40702810102300000001\n\t\t\t\t\t\t\t\n\t\t\t\ + \t\t\t\t\t044525593\n\t\t\t\t\t\t\t\t30101810200000000593\n\ + \t\t\t\t\t\t\t\tАО \"АЛЬФА-БАНК\" г Москва\n\t\t\t\t\t\t\t\n\ + \t\t\t\t\t\t\t0665413230\n\t\t\t\t\t\t\t011206020\n\t\ + \t\t\t\t\t\tОбщество с ограниченной ответственностью \"Ромашка\"\n\ + \t\t\t\t\t\t\n\t\t\t\t\t\tпочтой\n\t\t\t\ + \t\t\t5\n\t\t\t\t\t\tШтраф ГИБДД\n\ + \t\t\t\t\t\t10.00\n\t\t\t\t\t\t01\n\ + \t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t044525593\n\ + \t\t\t\t\t30101810200000000593\n\t\t\t\t\tА\ + О \"АЛЬФА-БАНК\" г Москва\n\t\t\t\t\t\n\t\t\t\t\t\t02\n\ + \t\t\t\t\t\tИсполнен\n\t\t\t\t\t\n\t\t\t\t\n\ + \t\t\t\n\t\t\t\n\t\t\t\t044525593\n\t\t\t\ + \t30101810200000000593\n\t\t\t\tАО \"АЛЬФА\ + -БАНК\" г Москва\n\t\t\t\n\t\t\t0\n\ + \t\t\t80.00\n\t\t\t80.00\n\ + \t\t\n\t\t\n\t\t\n\t\n\t\n\t\t\n\t\t\t\n\t\ + \t\t\n\t\t\t\n\t\t\t\t\n\ + \t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\ + \tlGkg53OXMheb7EkknHQaiQCZCW8+Z9yhldjGj+3FcLa4HzAuzFzWMw8EYiLa2cGd\n\ + \t\t\t\n\t\t\n\t\tZglywuWbdNiPFnRkoj4wMkZbQwDtP/8HRZUWjINtGD+5Yiiab68o/ChvQG8z0v6O6upwmxUIgODa&#13;\n\ + \ ptKAzwmJR5g0ScbarcOTrIV3FjEkkOMQeg5H4ntCdQGDq8VxyxfCHtFFEMJ0/3TMzCzq330+voyL&#13;\n\ + \ KPKN4w3gyRn6H0rlNwbKXTYn2uJ5bNc1jTfhc+24GgqgDmFToej0POr3YwdnqFwL8RV/h3T83Buc&#13;\n\ + \ iBXoCxdhmJ5xGeEu6KTwERP2RQR3trBIOcRJU+wM/KqOWFnrREFHA5iw59xDG16AYp9F5LeE/9On&#13;\n\ + \ qpVSRZmksU3XZyoU+f25lZy4TiczYJHfLsLbbQ==\n \n\ + \t\t\n\t\t\t\n\t\t\t\tMIIGMzCCBBugAwIBAgIIQ+Ua6h49X/kwDQYJKoZIhvcNAQELBQAwgb0xCzAJBgNVBAYTAlJVMQ8w&#13;\n\ + \ DQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEWMBQGA1UEChMNSlNDIEFsZmEtQmFuazEl&#13;\n\ + \ MCMGA1UECxMcRGlnaXRhbCBTZXJ2aWNlcyBEZXZlbG9wbWVudDEeMBwGA1UEAxMVQWxmYVRydXN0&#13;\n\ + \ Q29yZSBDQSBSb290MS0wKwYJKoZIhvcNAQkBFh50cnVzdGNvcmVfc3VwcG9ydEBhbGZhLmJhbmsu&#13;\n\ + \ cnUwHhcNMjQwNTI3MTMzNTAwWhcNMjkwNTI3MTMzNTAwWjCByTELMAkGA1UEBhMCUlUxDzANBgNV&#13;\n\ + \ BAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MRYwFAYDVQQKEw1KU0MgQWxmYS1CYW5rMSUwIwYD&#13;\n\ + \ VQQLExxEaWdpdGFsIFNlcnZpY2VzIERldmVsb3BtZW50MSswKQYDVQQDEyJURVNUIFRydXN0Q29y&#13;\n\ + \ ZVJTQSBTaWduZXIyIDIwNDggYml0MSwwKgYJKoZIhvcNAQkBFh10cnVzdGNvcmVfc3VwcG9ydEBh&#13;\n\ + \ bGZhYmFuay5ydTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbaUlic4XF47DJtoFQK&#13;\n\ + \ Nnd46jvaoE9pyxByuEKQkZY8Na5XWNuyr5ZALF6RTYXRS+i2wqig+zsGhEKG5rM2VZFJB4p6Vvwb&#13;\n\ + \ ULzDeH08tEw01hvnIiUFxrlVlpMIM649rLaMUTZnh8RKq23WkvDxPaEEeLV0f0sgeHpBf2nV7ZeM&#13;\n\ + \ 4w6LdC2T/hnYAy7VxIS+BN2nDGOIePqh+lGgUZIHY9cO3IbN7yWSQQSC7hQ696RC9L5vWedOXb6C&#13;\n\ + \ myWlFsuOnAgp+O3z2U1wbovCQ48CU8VprzjLorw/UTz/qJr7uGGICuY7M1Go7qLvICsHclkKqvRc&#13;\n\ + \ CMLBGxdg6RBkA+6t96cCAwEAAaOCAScwggEjMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFp1la5Q&#13;\n\ + \ GzpdMD7SCyadt9CVfElrMAsGA1UdDwQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAwYIKwYBBQUH&#13;\n\ + \ AwQwgccGA1UdHwSBvzCBvDA8oDqgOIY2aHR0cDovL2FydGFwcC9hcnRpZmFjdG9yeS9UcnVzdENv&#13;\n\ + \ cmUvQ1JMcy90cnVzdGNvcmUuY3JsMDqgOKA2hjRodHRwOi8vaGF2ZW4ubW9zY293LmFsZmFpbnRy&#13;\n\ + \ YS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMECgPqA8hjpodHRwOi8vczAxZHBydXByYnMubW9zY293&#13;\n\ + \ LmFsZmFpbnRyYS5uZXQ6ODA4MC90cnVzdGNvcmUuY3JsMA0GCSqGSIb3DQEBCwUAA4ICAQARCvm8&#13;\n\ + \ JwBOGonGKMlnwyxnFX2aV1qIkzMgo7ILaCXT/MybvPH/3GQByBOUsASFU7cod57qEOOyQSN/JTQ/&#13;\n\ + \ ZdKz3B8goGoO1XC/toybaTib92Dru7XyiJAeOLHksDjMQ7U6Xgk/51xoPa6AvZyOUWNW0KUdQFWl&#13;\n\ + \ fyJeH+Gt4Xr1OH+LYuUMhiVubUPn+edW/PW8WTzlpjvd55/e69YViSJBuNenV0cmxKe/xWD7ZnfG&#13;\n\ + \ fBsf+Sy/xhfjP0nFd7qANeQJXmb07gl7zJUyV0oK7fXyHO7Rg2wVcWEr8p9uS/sTS0ZnXJZKN3/O&#13;\n\ + \ O+zp9UPM23uzZNuySsBbc7QNlJ3c8GLL/R93xvE3BNV+DtZVbu7xaqcWZmFEnfp0iTVCfMC3d9Ci&#13;\n\ + \ g+KZ5NKBQp+vB0A4+vj8jO/ZCCjtho3nqeJ+exO2AHgLYj6XaeCTed4fW0ENt0XWNrFaVW/wRyHO&#13;\n\ + \ XvEN8Ocj8LV5Xtwh6xPuwSbas2VL4v7V50O7V5RA4ZucdpdmRj5z/qkqkirGRcWnf+UWwjniI+Bz&#13;\n\ + \ CGlsPjGJmGgl8OjGUnb/vZ4fN1g2QVBcS1riln0mQDPbaBJNtFOSc3GCh+HttX075tinnux348Yg&#13;\n\ + \ qsHeKfsVZ6+5gmrumdaS8uN/L/cgFtPJFfwpbz5YGq98owU8BVlodP1eM8C5eEPU1X0BGQ==\n\ + \ \n\t\t\t\n\t\t\n\t\ + \n\n" + ResponseSignedEncrypted: + summary: Пример подписанного и зашифрованного ответа + value: | + YsMGdo6pSe1obzC5DCwW51kSok0LsJ0lIM45IcJ0AGPxJg/HdHqBIsf5i0udVnNzALbileuwBoAWwcwiU4iCo2xwDrYaU88Csz3s1wnomqaoQ/h9LLHbTzuZjBm4Uo58nDVbuZ242PZ8T4M4M4I22zmDM6YLW0DgTLpR4QXoq7H+gdSBbc8nQ0Bobca2/z1IBcTPmdobrouyWct4cJ/2H+tbN0873PpOWB0+SQdTZ9/swh/4Pk4OEQmvdxMlccg/ZOrvF+chJxtpdiUFucGdqIgko3YO9FJnCxJY/ycAT90w2ogJqgSaOZTb1yQyfSVQV2oZGDaE8ivc58UwGtfARmnA1rmaFY9SWahbwDE+IhZ77Y/6ymITgkutLpKNlyJfr0phMp6GTUfPwv9HjxmFnvCLuv2Ucc04/gYBx/PvrAwjOxxKUAFOsniWxWw/3eoE5dNBqPI9eya376nUnU09LX7rN5BGpNqKu9UX2Q0br5ee0voKBd/ZFnYbKUJc+1o0DHjW44z+G+HAlvmAQw3c/PqDjX59z1KnBphF/WcyeFGdX8fniEwt3EIEGDYgkKGBSPbpE+Xm42M/t85070xJpReUQtPvfLHA+1DcxLA7RtX0CVfas3GhoHfMLbNCs9q5klxDJD+9v3dk1SbIY+JqAb/JDRAUB9rV9jqTOEMpwNz4jYOeQUm+bxGHZ+AS4ce1U303tKXUnUWlNN8+U8G29mxbIw0JM7mgwDkzvPWGpoEEFGDGcWuYEXEJx/EM5VnPf8xy5SmG5wQISd7CX2KTYic1kda/eBq9Akk4X5Y6GWImqP6pJMG9XIgaqj9Uf7UbZBUMqxwnEIxLXSp3KPOSUlOiHeEOTttbTgbDN4PK/VPGLoHOgLRmHvzy0xQQZhjbu6PZgCp/WK2w0T95w0uh8lU7GxWCAkHZRREftlYtSdaHglQPzsmNybu566+KTklKzdwhWl2tetboM6CY9lKLRfKbqgwZ0ggFPM/2K1xNYJRWdkzkED4UN40UVZ7SwB0RcoJNxmPB/xlOFyOXTLEhmbdB5W63NQT0l3+YIxuISfblcKba4zvsp6YcAP9q0mTtAHU06VFUg9PRGXonTyHTtknh95WBEJdjcqyvc78Mkq3rYPxYdKPuTaVXE6hLKk7+xuOzb4ty3kkSaJiM57X/YBgx1eRo5uwBtK65iCl4BPaqgEmlZQmqWwgZyC4bcOqaeSCIxikc50ymbQlMMek5jaJ9AseGvYNU89NB7OHVaG2xqRd6NOKsGTqJHLXSZwGVlV+elzlu0mava9V1Qy6x/pGDHI0oatAMLxEuNmrOmCYViIuP9eOrM7qf30AYdtMylzJJLvwfN3T94pPBFP1qtwiNq37j/LnZRvpIJc15QpEtby4exAjHxl6pEbCsslfLdXkEvM2Rwc1Ax8w9o2Nf4U1/OSkqyJ2cnmMOlJT6UUL3r8yEMbg/SQDvvJnB1Dpt8I0k4KHZmM16YmpjyClkXZUTQZWHjkhBew+qyONQqJQQGze5+FxDW0y1NJ9zi0MJ4RoLKkyeorpFmAVm1NrzkmMDWm+l+qucg4XHchrC/SoWDEgJDb8tORJfX3vlKiouaeiIw0Y1qmuhUDw0UuQBQFZURR64eTAhiWnbwhrfprOxSV/tbxlo8YtLglnZqvNKpRbL0zzszvfbPHRUF9s1wT7PXCawUA0I1jb4jQNDb/VbF1ymu4ZlrfNPWDmDitkHeHvPWwk8K//WCW6f6yben/9BTvRjwxCAXT+EiktCIAXLAbI3ZD4gkw8e/cLd9WXRTHsW0hVUVOiVFdQicfT6RWpRv+eqYnDrdAPM5beHLuyxgE6/PTnS+mi8KMLEu6z+Ton6aJg2xYnhIbVREqF3wAYS2gxD6Ijg+rqy1JMGtUrZa++a2+HyD5t0bE26DMNjDj4Z1l2FVp2VXN7SWvJs4eG6q7AdZUs8FChDWry544llCOHPUXyYJ65/e6ZEBm18A7iV+/UAH3fJ88kOqWMxrqlr2lKflK0khU8YQTJOa1emcczFZAB7VHuvqjqtbfoKHsKEfuzKAr1Wggq4/hglMRkstcFtaxTWgheJdMkgIn53EedxW9mD+AZf2F4xg5Q9VpnApPfP3Isn2muQ4KpT5xIJE/oLCozqN4/pL46WanyuP5ogrg7AE7n5aRwD0RVQirSe2K3sjAEw/59U5fuE4Gj8xoycst4UNpa856iWC4CksTs8RmCIZoCaVIGZEWENR2HzFIjWTPk4BpqY+zt3wjVS5jKX8FDlh1dOCDgiizr44ZX8JZL+pUuyeNna/UcBDpkw+rffKlLxLjmeKtLv6GDRp5GL+mKOmbShmXJbH2y5AdtbxCDA1sVWbkgmNWsjsw8Bt9Vqrp4ME3TakSUTRh2Oy9ygokDGtQQDNNYWHteNapqgqqWb1Kxk2PUwCSnotcOOh9iiOgBtoKSKEfJ/Bh/W1Ta2Wu77//K5A1bUZlGe4dYj/NTJ65Ry8KG43l2yKZG7hkfu6O6fjpLeHeaLzO/f3JNtRM2qBf9SRXFFG6i3nflpuhT35c1+w6aHxNGtWePpj62drJtJNG5qFVrruHcYWxE1GihRUHdvkCZAUydROWLjmo6vYi5T+XjQraDy9wdi6FYRSPnqJZsgrRQk5aFrY41s5YtfRlovDOPehEZfSAypNsijGiRQOsT0GrCHq5fH7DWPT42KF08rqeHX4emHREVee4pwlRHIk5190MG6UpIE3pleWliNAJGZQ5zpGktf37HrYY/M0cjhzW3u3IV0xpbptKocatR2Bb+0iQrNp+9uCX1Ko9LyC6MD+4d4deGFQjG3b6u9phrXMYFU2vZuULpjX1V0BaEdc6j48IUdKY1nMtQR2hX+We+mEqkYZjtji1qo7AhfvelTX4ELlnRKw/Dj1qskv7ZrvuCLUd8e2x3e4ktR4eHuds9mKpCxnpMHjcnOG1C2jfFyILrabPsn0ea2RK2CCTdPT1B91BEKYWR5W2sSaTQLy1VNN9UM/LvCgL/KMkSLkR12feGmujFKnAyaF1LgaZwXyRWUKj8fRKPQtYmA8i4DNWOIOoUln2ABLsLg4LfY0D45TZGQN6HszaHwdlEbTQwYLp71vIlZq3O1EyEIL1Jom3SpjtLR5P81QOUyHeBHivc5SJnwjcm7a3YcqcXf/YDPJDcCEDQHIJb0/AlkQ4+HLj3HY6XYnb1qE1A1+/H606xNi2NmQDOyYeLCb0XxkljymTCTlIK2uU7h47GaCVgtdEEM5D4pMnisEPBtkitDAFZV67FuBDPm5eJjh8VLoh5omhsR9K9DTWDDW0RT2Cq/hB0Kmc6FdhbszsMKOrd/0VAVbmykJF2sA2kemF5CN6LZG3dq63P2fdB96HxhBw0dmnhxBCidqLVQsjWuEfcgwqOXU4QCDdLcU0ZlRXgu3A6JJIPKMSLmcrUPyXZyOBnmB9WFIZGUUY3+FGWVJltKb1N6h7sO6mYF5s/7p8rLa+WgwjBLbx6GNq8T2fKSmeulK2RECO2IFKzu0DvsTOrqDp/KUUIWhUCFVr4VEgNoS6kbuEZN99EX0WV9RqjXz1qMNCV2YYrqStwP0UumjvzvYm2fbXJJdK/bykrbgK4zdN9n3uagtcY+l0jkIeh3y3JYk/Y/lpSpW+g5UCZNEYLejnyeC8C8Anhq7MlWUKyRvmzPRN09Te7SNShIo6tXEnMkws6K9PMpOJu2iZJhU/R5BRePUKjpf0fQglUJok2LwqC4FNBVk8AJsGdYar6VYReYCjcq6suv/EUPlZNJYu+kMNR2+2bfM1mx/KBe0tpRCeMY7tTVhst7yMVlVIFJ4cBeqC0yZO93mzXB1gRvE0raivsvFrtg9oQ0DVrCosxcR1zXpIojejRu62eSf/uNOzmssi5MX1Q0Okh1+VgEr1YTfJmkvVhCJfTe1uxfJ6x4RTUTIcDNtDGYjN62GCWWZfQEW+7q1MnteavJg8r1HQxtL1lhM/KG76KMSVhQZ/viGxkN1TpmbS2ydeNk7zkDwVP3fIj5h4lyzdL3EmTKuGr99eSJwDUewI9Cn7bQuJVp9l3dSf4jjbqXknU1DugJr/n + ResponseGetFileTransaction: + summary: Пример ответа + value: + requestId: 67e50b09-a203-4119-86cb-647d06a803a0 + status: SUCCEED + downloadFileLinks: + - url: https://baas.alfabank.ru/filebox/secure-file-transfer.outgoing-files.to-processing/f190bfef-aad6-ce9b-9224-f11ef60564cb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230608T152952Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=secure-file-transfer%2F20230608%2Fdev%2Fs3%2Faws4_request&X-Amz-Signature=36ef1ccf28bdf6e54710fc3c1dd235c8f383275c2bbb0c9db365da272d3c24a8 + method: GET + RequestCreateStatements: + summary: "Пример запроса. Важно, убрать форматирование!" + value: "{\"Data\":{\"Statement\":{\"accountId\":\"12345678-1234-1234-1234-1234567890AB\"\ + ,\"fromBookingDateTime\":\"2019-09-03T00:00:00+00:00\",\"toBookingDateTime\"\ + :\"2019-09-03T00:00:00+00:00\"}}}" + postIssueResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T05:32:37.509Z + id: 62550ef50163785f2222707e + type: issueRsaCertificate + status: CREATED + getIssueResponseExample: + summary: Пример ответа + value: + requestActivateRsaCertificate: + - creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T07:46:58.691Z + id: 62550ef50163785f2222707e + type: activationRsaCertificate + results: + userSignMethodStatus: ENABLED + userSignMethodType: RSA + status: FINISHED + finishedDate: 2022-04-12T07:49:56.328Z + requestIssueRsaCertificate: + - creator: Ефимов Филипп Архипович + createdDate: 22022-04-12T07:46:58.691Z + id: 62550ef50163785f2222707e + type: issueRsaCertificate + results: + owner: Ефимов Филипп Архипович + notAfter: 2024-04-12T07:49:27Z + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2022-04-12T07:49:56.110Z + executionDate: 2022-04-12T07:49:56.163Z + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2022-04-12T07:39:27Z + caRequestId: 220220 + status: FINISHED + finishedDate: 2022-04-12T07:49:56.328Z + requestCurrentSignTypeRsa: + - creator: Ефимов Филипп Архипович + createdDate: 2022-09-22T10:35:03.304Z + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: FINISHED + finishedDate: 2022-09-22T10:35:39.967Z + requestSwitchRsaCertificate: + - creator: Ефимов Филипп Архипович + createdDate: 2022-09-22T10:35:03.304Z + id: 62550ef50163785f2222707e + type: switchRsaCertificate + status: FINISHED + finishedDate: 2022-09-22T10:35:39.967Z + requestRevocationRsaCertificate: + - creator: Ефимов Филипп Архипович + createdDate: 2022-09-22T10:35:03.304Z + id: 62550ef50163785f2222707e + type: revocationRsaCertificate + status: FINISHED + finishedDate: 2022-09-22T10:35:39.967Z + requestReissueRsaCertificate: + - creator: Ефимов Филипп Архипович + createdDate: 22022-04-12T07:46:58.691Z + id: 62550ef50163785f2222707e + type: reissueRsaCertificate + results: + owner: Ефимов Филипп Архипович + notAfter: 2024-04-12T07:49:27Z + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + sendDate: 2022-04-12T07:49:56.110Z + executionDate: 2022-04-12T07:49:56.163Z + thumbprint: f738ec7266d1e3f6d6d4557bcbbc43ec188db3cf + dn: + firstName: Филипп + lastName: Ефимов + country: RU + fullName: Ефимов Филипп Архипович + email: User176@pochtochka.com + issuedCertificateId: 62552f2457595f1652c4b179 + notBefore: 2022-04-12T07:39:27Z + caRequestId: 220220 + status: FINISHED + finishedDate: 2022-04-12T07:49:56.328Z + getRsaResponseExample: + summary: Пример ответа + value: + certificate: + owner: Ефимов Филипп Архипович + tokenSerialNumber: 00a81050 + notAfter: 2024-04-12T07:49:27Z + serialNumber: 6100035c3cff88cd00f01d734a000100035c3c + expireSoon: true + id: 62552f2457595f1652c4b179 + tokenKeyId: "AlboKey_{BBB5EB5D-2B38-488B-B9E2-5E336DDE3DE9}" + actions: + - available: true + type: UPLOAD_ON_TOKEN + - available: true + type: UPLOAD_ON_TOKEN + notBefore: 2022-04-12T07:39:27Z + status: CERT_VALID + uploadOnToken: true + content: MIIFzDCCBICgAwIBAgITYQADXDz/iM0A8B1zSgABAANcPDBBBgkqhkiG9w0BAQow\r\nNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUA\r\nogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UE\r\nCxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENB\r\nIDEwHhcNMjIwNDEyMDczOTI3WhcNMjQwNDEyMDc0OTI3WjCBmTEVMBMGA1UEKgwM\r\n0KTQuNC70LjQv9C/MRUwEwYDVQQEDAzQldGE0LjQvNC+0LIxCzAJBgNVBAYTAlJV\r\nMTUwMwYDVQQDDCzQldGE0LjQvNC+0LIg0KTQuNC70LjQv9C/INCQ0YDRhdC40L/Q\r\nvtCy0LjRhzElMCMGCSqGSIb3DQEJARYWVXNlcjE3NkBwb2NodG9jaGthLmNvbTCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKJu1IfZg/ijEVWCIC8t20Bm\r\nmdUNY1k2ACcIRDA1s8hClq9jc56gj9o1yFeDBOfa73J6M4IS7xD7H75FANdV5K89\r\nyJUjN8MnkTHYw/MnJKujeI+NP4cIhO7+x11W/cufPmSg3M4DlGKFND62gey82Ajb\r\n9oshMFdUzgm2RDR7Oo2xcMWpWvRfCz/fGPfcGGENcOsLbiK+cOyljBuN69utzn8v\r\n+YWGQdhfmkImjFw13lPwmtVQLWqQEiacUDQLl0wALqpaWCUgbsECSpzhn9u7RbES\r\nqyLTfncGWcP0D/eTh65jm+ZVGfab/oSzz0rleuepFhqnn+jrORCzrifscsNDwXcC\r\nAwEAAaOCAeAwggHcMB0GA1UdDgQWBBTbfzj1CFqgIOUtAqiQPszkaMdawzAfBgNV\r\nHSMEGDAWgBTJFzMem6mUoJYYS25xTIHb6XP+ZTCBuwYDVR0fBIGzMIGwMIGtoIGq\r\noIGnhjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZh\r\nLUJhbmtfU0NBMS5jcmyGMGh0dHA6Ly92bGt3czY6OTA4MS9kaXN0cnBvaW50L0Fs\r\nZmEtQmFua19TQ0ExLmNybIY4aHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlz\r\ndHJwb2ludC9BbGZhLUJhbmtfU0NBMS5jcmwwgdsGCCsGAQUFBwEBBIHOMIHLMEUG\r\nCCsGAQUFBzAChjlodHRwczovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2lu\r\ndC9BbGZhLUJhbmtfU0NBMS5jcnQwPAYIKwYBBQUHMAKGMGh0dHA6Ly92bGt3czY6\r\nOTA4MS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBEBggrBgEFBQcwAoY4\r\naHR0cDovL3Rlc3RqbWIuYWxmYWJhbmsucnUvZGlzdHJwb2ludC9BbGZhLUJhbmtf\r\nU0NBMS5jcnQwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgMFAKEcMBoGCSqG\r\nSIb3DQEBCDANBglghkgBZQMEAgMFAKIDAgFAA4IBAQA7qvezzVUukOu6PusP9Ulr\r\n801fn7lJlEG4suRmmqWTaOUkkwfoOV+AjyN4K9LtF8JF4BE7ovoz+BAXNl6IIaxB\r\nLup0lnIf2UUXvg8XoAZ9SCNnDdmHI05NrONrRg+7DyCv8FpyudFTkFhmkaMojuUH\r\nZN8V27KlW3Q0ijDrOyn9/rIqAIA5JVbvUfRIMR8DXpZsIkf0HAnZN4Zswn0U5U0K\r\n46Ewva4fWvF7u3638Hkv8u5XNU6E1eaJTWxVM+4J8HdnnTDHSDO27VFh9SxCP8E7\r\ncvQhIhfOXz2qESMSnC2bmlGm863E7fMGxNIpikE2D5LO8Z0KiI0qrhZA7p4tye2c\r\n + postActivateResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T05:32:37.509Z + id: 62550ef50163785f2222707e + type: activationRsaCertificate + status: CREATED + putSignSettingResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-09-21T22:15:47.500Z + id: 62550ef50163785f2222707e + type: currentSignTypeRsa + status: CREATED + postRevocationResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T05:32:37.509Z + id: 62550ef50163785f2222707e + type: revocationRsaCertificate + status: CREATED + postSwitchResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T05:32:37.509Z + id: 62550ef50163785f2222707e + type: switchRsaCertificate + status: CREATED + postReissueResponseExample: + summary: Пример ответа + value: + creator: Ефимов Филипп Архипович + createdDate: 2022-04-12T05:32:37.509Z + id: 62550ef50163785f2222707e + type: reissueRsaCertificate + status: CREATED + enableQesResponseExample: + summary: Пример ответа + value: + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + status: CREATED + createdBy: Дмитриев Денис Михайлович + createdAt: 2022-09-05T14:39:51.197Z + qesRequestsPostRequestExample: + summary: Пример запроса + value: + type: enableQesSignType + qesRequestsPostResponseExample: + summary: Пример ответа + value: + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + content: string + qesRequestsPatchRequestExample: + summary: Пример запроса + value: + type: enableQesSignType + signature: string + qesRequestsPatchResponseExample: + summary: Пример ответа + value: + id: 63160a37e27edd0c316567a6 + type: enableQesSignType + isSigned: true + downloadPoaRequestExample: + summary: Пример запроса + value: + poaNumber: 8e08423a-bcc0-4fba-a791-9825cb1a7cb3 + issuerInn: "7727464030" + confidantInn: "420548688683" + downloadPoaResponseExample: + summary: Пример ответа + value: + id: 3fa85f64-5717-4562-b3fc-2c963f66afa6 + createPaymentRequest: + summary: Пример запроса + value: + amount: 1.01 + date: 2022-10-11 + deliveryKind: электронно + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-05-25 + paymentKind110: "0" + digestSignatures: + - base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + externalId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + incomeTypeCode: "2" + number: "1047" + operationCode: "01" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerAccount: "40702810102300000001" + payerBankBic: "044525593" + payerBankCorrAccount: "30101810200000000593" + payerInn: "0453438040" + payerKpp: "046773311" + payerName: Общество с ограниченной ответственностью "Клиент" + priority: "5" + purpose: Оплата заказа №1. НДС не облагается + urgencyCode: NORMAL + vat: + rate: "0" + type: NO_VAT + createPaymentResponse: + summary: Пример ответа + value: + amount: 1.01 + bankComment: "" + bankStatus: CREATED + crucialFieldsHash: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + date: 2022-10-11 + deliveryKind: электронно + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-05-25 + paymentKind110: "0" + externalId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + incomeTypeCode: "2" + number: "1047" + operationCode: "01" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerAccount: "40702810102300000001" + payerBankBic: "044525593" + payerBankCorrAccount: "30101810200000000593" + payerInn: "0453438040" + payerKpp: "046773311" + payerName: Общество с ограниченной ответственностью "Клиент" + priority: "5" + purpose: Оплата заказа №1. НДС не облагается + urgencyCode: NORMAL + vat: + rate: "0" + type: NO_VAT + getPaymentStatusResponse: + summary: Пример ответа + value: + bankStatus: ACCEPTED + bankComment: Отправим платёж в течение банковского дня + crucialFieldsHash: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + patchPaymentStateResponse: + summary: Пример ответа + value: + bankStatus: PARTSIGNED + bankComment: null + crucialFieldsHash: 3ba4cecce366c3ad8db6edafb71052b37a8a1acc8013ff565879d8711c0c4316 + fromInvoiceRequest: + summary: Пример запроса + value: + amount: 1.01 + date: 2018-12-31 + deliveryKind: электронно + expirationDate: 2022-09-12T19:15:51+03:00 + externalId: 5863d914-80ee-4e27-9041-49e8136ab94e + operationCode: "01" + orderNumber: "1" + payeeAccount: "40807810201300000043" + paymentNumber: "1" + priority: "5" + purpose: Оплата заказа №1. НДС не облагается + urgencyCode: NORMAL + vat: + rate: "0" + type: NO_VAT + fromInvoiceResponse: + summary: Пример ответа + value: + amount: 1.01 + bankComment: "" + bankStatus: CREATED + crucialFieldsHash: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + date: 2018-12-31 + deliveryKind: электронно + externalId: 5863d914-80ee-4e27-9041-49e8136ab94e + incomeTypeCode: null + number: "1" + operationCode: "01" + payeeAccount: "40807810201300000043" + payeeBankBic: "044525593" + payeeBankCorrAccount: "30101810200000000593" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerAccount: null + payerBankBic: null + payerBankCorrAccount: null + payerInn: null + payerKpp: null + payerName: null + priority: "5" + purpose: Оплата заказа №1. НДС не облагается + urgencyCode: NORMAL + vat: + rate: "0" + type: NO_VAT + fromInvoiceBudgetRequest: + summary: Пример запроса + value: + amount: 100 + date: 2022-04-01 + deliveryKind: электронно + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-03-25 + externalId: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + operationCode: "01" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerKpp: "772201001" + paymentNumber: "1" + priority: "5" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + urgencyCode: NORMAL + fromInvoiceBudgetResponse: + summary: Пример ответа + value: + amount: 100 + bankComment: null + bankStatus: CREATED + crucialFieldsHash: 925a81c0d635559af364262b9ed5f0972c0bab64dd03189b511bc0e4cdc80d50 + date: 2022-04-01 + deliveryKind: электронно + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-03-25 + externalId: 697e31f1-8df2-458e-8646-f77ea5bae8a2 + number: "1" + operationCode: "01" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payerKpp: "772201001" + priority: "5" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + urgencyCode: NORMAL + CreateRegistryRequest: + summary: Пример запроса + value: + urgencyCode: NORMAL + description: Описание реестра + payments: + - number: "1" + date: 2022-04-01 + deliveryKind: электронно + amount: 100 + payerName: Общество с ограниченной ответственностью "Клиент" + payerInn: "7736576798" + payerKpp: "772201001" + payerAccount: "40702810102300000001" + payerBankBic: "044525593" + payerBankCorrAccount: "30101810200000000593" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-03-25 + priority: "5" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + - number: "2" + date: 2022-04-01 + deliveryKind: электронно + amount: 100 + payerName: Общество с ограниченной ответственностью "Клиент" + payerInn: "7736576798" + payerKpp: "772201001" + payerAccount: "40702810102300000001" + payerBankBic: "044525593" + payerBankCorrAccount: "30101810200000000593" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + payeeBankCorrAccount: "30101810800000000745" + departmentalInfo: + uip: "0" + drawerStatus101: "01" + kbk: "18210102010011000110" + oktmo: "45902000" + reasonCode106: ТП + taxPeriod107: МС.02.2022 + docNumber108: "000000000000001" + docDate109: 2022-03-25 + priority: "5" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + CreateRegistryResponse: + summary: Пример ответа + value: + registryId: U102702240001208 + description: Описание реестра + payerAccount: "40702810102300000001" + urgencyCode: NORMAL + paymentsCount: 1 + totalAmount: 100 + GetRegistryResponse: + summary: Пример ответа + value: + status: UPLOADED + description: Описание реестра + payerName: Общество с ограниченной ответственностью "Клиент" + payerAccount: "40702810102300000001" + urgencyCode: NORMAL + registryActualState: + paymentsCount: 1 + totalAmount: 100.0 + states: + - count: 1 + amount: 100.0 + status: DRAFT + isValidForSign: true + UpdateRegistryStatusResponse: + summary: Пример ответа + value: + status: ON_SIGNING + description: Описание реестра + payerAccount: "40702810102300000001" + urgencyCode: NORMAL + content: YW1vdW50PTEwMC4wMApkYXRlPTIwMTgtMDUtMzEKZGVwYXJ0bWVudGFsSW5mby...NOdW1iZXIx= + GetRegistryPaymentsResponse: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + payments: + - id: U031308240002351 + number: "1" + status: DRAFT + date: 2022-04-01 + amount: 100 + payerAccount: "40702810102300000001" + payeeName: Общество с ограниченной ответственностью "Центр "ИННОВАЦИЯ" + payeeInn: "7723870785" + payeeKpp: "553453453" + payeeAccount: "40702810564564564531" + payeeBankBic: "040173745" + purpose: Налог на доходы физических лиц за февраль 2022 года. НДС не облагается + SignRegistryRequest: + summary: Пример запроса + value: + digestSignatures: + - base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + signatureType: RSA + GetSignResultRsa: + summary: Успешное подписание RSA + value: + status: SIGNED + digestSignatures: + - certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + signatureType: RSA + status: SIGNED + GetSignResultPartially: + summary: Частичное подписание + value: + status: PARTIALLY_SIGNED + digestSignatures: + - certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + signatureType: RSA + status: SIGNED + - certificateUuid: 51999366d11e143acbc03a56d70001000866c1 + signatureType: RSA + status: FAILED + errorCode: signature_error + errorMessage: The certificate you are attempting to use to sign the document + is not associated with your organization. + GetSignResultQes: + summary: Ошибка при подписании КЭП + value: + status: ERROR + error: + code: signing_failed + message: All signing attempts failed. No signatures were applied to the + payment register. + digestSignatures: + - signatureType: QES + status: FAILED + errorCode: signature_error + errorMessage: Insufficient permissions to perform the operation. + getBuildProjectsResponseExample: + summary: Пример ответа + value: + - area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + getEscrowOrdersV0ResponseExample: + summary: Пример ответа + value: + pagination: + offset: 0 + limit: 10 + totalCount: 25 + items: + escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-31 + referenceID: EA10509220000013 + status: VERIFICATION + postEscrowOrdersRequestExample: + summary: Пример запроса + value: + escrowAccount: + amount: 112500 + currency: RUR + estateObject: + flat: "1" + buildProject: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + type: APARTMENTS + depositor: + lastName: Федькин + firstName: Ратибор + birthdate: 1990-08-30 + phoneNumber: "75453333435" + identityDocumentNumber: "197343" + dateIssuedId: 2020-01-01 + identityDocumentType: "001" + middleName: Васильевич + identityDocumentSeries: "5516" + equalityAgreement: + date: 2020-01-01 + number: "5555" + getEscrowOrdersV1ResponseExample: + summary: Пример ответа + value: + pagination: + offset: 0 + limit: 10 + totalCount: 25 + items: + escrowAccount: + amount: 6000000.12 + currency: RUR + accountNumber: "40702810701300000761" + fullNameDepositor: Королёв Митрофан Гертрудович + buildingPermitNumber: 61-310-998601-2022 + creationDate: 2021-12-31 + referenceID: EA10509220000013 + status: DRAFT + getEscrowOrderV0ResponseExample: + summary: Пример ответа + value: + escrowAccount: + amount: 8.008281904619307E11 + currency: RUR + accountNumber: "40824810906580000000" + estateObject: + flat: "234" + buildProject: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + type: APARTMENTS + rejectReason: "К сожалению, во время обработки произошла тех. ошибка." + depositor: + birthdate: 1998-11-03 + phoneNumber: "79055485717" + identityDocumentNumber: "615760" + dateIssuedId: 2022-04-25 + identityDocumentType: "001" + fullName: Королёв Митрофан Гертрудович + identityDocumentSeries: "8039" + creationDate: 2021-12-31 + referenceID: EA10808220000061 + equalityAgreement: + date: 2022-07-14 + number: "234" + isRegistered: false + status: VERIFICATION + getEscrowOrderV1ResponseExample: + summary: Пример ответа + value: + escrowAccount: + amount: 8.008281904619307E11 + currency: RUR + accountNumber: "40824810906580000000" + estateObject: + flat: "234" + buildProject: + area: ОКТЯБРЬСКИЙ + country: RU + regionCode: "054" + buildingPermitDate: 2021-10-01 + city: Новосибирск + projectNumber: "162" + buildingPermitNumber: 61-310-998601-2022 + phases: + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + - street: 11-4 на земельном участке с к.н. 61:44:0073012:390 + termEscrowOrder: 2022-03-22 + name: поз. 4.1 - 9-этажный 4-х секц дом + index: 1 + house: "4.1" + building: "2" + settlement: Новосибирск + commercialName: ЖК ЗАПАДНЫЕ АЛЛЕИ + type: APARTMENTS + rejectReason: "К сожалению, во время обработки произошла тех. ошибка." + depositor: + birthdate: 1998-11-03 + phoneNumber: "79055485717" + identityDocumentNumber: "615760" + dateIssuedId: 2022-04-25 + identityDocumentType: "001" + fullName: Королёв Митрофан Гертрудович + identityDocumentSeries: "8039" + creationDate: 2021-12-31 + referenceID: EA10808220000061 + equalityAgreement: + date: 2022-07-14 + number: "234" + isRegistered: false + status: DRAFT + escrowOrderCancelV1ResponseExample: + summary: Пример ответа + value: + referenceID: EA13110220000011 + status: CLIENT_CANCELLED + postExecuteRequestExample: + summary: Пример запроса + value: + equalityAgreement: + isRegistered: true + postEscrowOrdersFullRequestExample: + summary: Пример запроса + value: + escrowAccount: + amount: 112500 + currency: RUR + estateObject: + flat: "1" + buildProject: + buildingPermitNumber: 61-310-998601-2022 + phases: + index: 1 + type: APARTMENTS + depositor: + lastName: Федькин + firstName: Ратибор + middleName: Васильевич + birthdate: 1990-08-30 + phoneNumber: "75453333435" + identityDocumentNumber: "197343" + identityDocumentSeries: "5516" + identityDocumentType: "001" + dateIssuedId: 2020-01-01 + birthPlace: г. Москва + regAddress: "Ул. Соцветий, д12, кв. 1" + managerContactPhoneNumber: "75453333435" + managerContactEmail: manager@gmail.com + equalityAgreement: + date: 2020-01-01 + number: "5555" + postEscrowOrdersFullResponseExample: + summary: Пример ответа + value: + referenceID: EA13110220000011 + status: VERIFICATION + getEscrowReportsV1ResponseExample: + summary: Пример ответа + value: + organizationName: Тестовый пользователь + organizationFullName: Тестовый пользователь Номер один Отозвана лицензия + buildProjects: + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + commercialName: Тестовый жилой комплекс + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - index: 1 + name: Дом + termEscrowOrder: 2024-02-10T00:00:00.000Z + - index: 2 + name: Паркинг + termEscrowOrder: 2024-02-10T00:00:00.000Z + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-303 + commercialName: Тестовый жилой комплекс 2 + actualProjectCompletionDate: 2024-02-11T00:00:00.000Z + phases: + - index: 1 + name: Дом + termEscrowOrder: 2024-02-10T00:00:00.000Z + - index: 2 + name: Паркинг + termEscrowOrder: 2024-02-10T00:00:00.000Z + postEscrowReportsV1RequestExample: + summary: Пример запроса + value: + buildProjects: + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-302 + commercialName: Тестовый жилой комплекс + actualProjectCompletionDate: 2024-02-10T00:00:00.000Z + phases: + - index: 1 + name: Дом + termEscrowOrder: 2024-02-10T00:00:00.000Z + - index: 2 + name: Паркинг + termEscrowOrder: 2024-02-10T00:00:00.000Z + - buildPermitNumber: №599-35-92-2024 + projectNumber: 503-303 + commercialName: Тестовый жилой комплекс 2 + actualProjectCompletionDate: 2024-02-11T00:00:00.000Z + phases: + - index: 1 + name: Дом + termEscrowOrder: 2024-02-10T00:00:00.000Z + - index: 2 + name: Паркинг + termEscrowOrder: 2024-02-10T00:00:00.000Z + showAccountTransactions: true + postEscrowReportsV1ResponseExample: + summary: Пример ответа + value: + report: + pagination: + limit: 10 + offset: 0 + totalCount: 2 + commonInfo: + customerNameTo: Тестовая организация ИНН 000000000 + periodTo: 2024-11-11T00:00:00.000Z + periodFrom: 2022-11-11T00:00:00.000Z + reportGenerationDate: 2024-11-11T00:00:00.000Z + escrowAccountInfo: + - buildPermitNumber: №599-35-92-2024 + commercialName: Тестовый жилой комплекс + buildProjectPhase: 2 + phaseDescription: Паркинг + escrowAccountNumber: "40824810906580012508" + escrowAccountCurrentStatus: Пополнен + escrowAccountOpenDate: 2023-08-15T00:00:00.000Z + apartmentCost: "12600000.55" + incomingBalance: "0.00" + outcomingBalance: "12600000.55" + balanceChange: "12600000.55" + depositCompletionDate: 2023-01-12T00:00:00.000Z + deponentName: Сергеев Сергей Сергеевич + deponentINN: "184514811334" + shareAgreementNumber: 22-444/111П-1234 + shareAgreementDate: 2023-07-10T00:00:00.000Z + assignmentAgreementNumber: ДУ 103-4 от 12.02.2023 + assignmentAgreementDate: 2023-08-31T00:00:00.000Z + escrowAccountCloseDate: 2024-08-31T00:00:00.000Z + isRegisteredShareAgreementProvided: "Y" + escrowAccountReservePlace: Онлайн + escrowAccountOpenPlace: Онлайн + developerManger: Иванов Иван Иванович + objectType: Комната + transactions: + - operationDate: 2023-07-20T00:00:00.000Z + transactionAmount: "150000.55" + primaryDocumentDate: 2023-07-20T00:00:00.000Z + primaryDocumentNumber: "350" + bicBank: "044525593" + - operationDate: 2023-07-16T00:00:00.000Z + transactionAmount: "50000.00" + primaryDocumentDate: 2023-07-15T00:00:00.000Z + primaryDocumentNumber: "75271" + bicBank: null + - buildPermitNumber: №500-35-92-2024 + commercialName: Тестовый жилой комплекс + buildProjectPhase: 1 + phaseDescription: Дом + escrowAccountNumber: "40824810906580012509" + escrowAccountCurrentStatus: Пополнен + escrowAccountOpenDate: null + apartmentCost: "22600000.00" + incomingBalance: "0.00" + outcomingBalance: "0.00" + balanceChange: "0.00" + depositCompletionDate: 2023-01-12T00:00:00.000Z + deponentName: Иванов Иван Иванович + deponentINN: "1845144457441" + shareAgreementNumber: 21-444/166П-55 + shareAgreementDate: 2023-01-21T00:00:00.000Z + assignmentAgreementNumber: ДУ/854-4 от 21.01.2022 + assignmentAgreementDate: 2023-08-15T00:00:00.000Z + escrowAccountCloseDate: null + isRegisteredShareAgreementProvided: "Y" + escrowAccountReservePlace: Онлайн + escrowAccountOpenPlace: Отделение + developerManger: Иванов Иван Иванович + objectType: Квартира + transactions: null + ScoringAnyResponseExample: + summary: Пример ScoringAnyResponse + value: + dealId: c5f72949-0e9a-41bf-a16d-a34b938f41ef + application: + platformId: B2B + borrower: + individual: + legalInfo: + inn: "770778659011" + kpp: "770201001" + ogrn: "305465110922043" + contactPhone: +7(495)545-00-10 + partner: + numberOfInteractionDays: 149 + startDateOfInteraction: 2022-05-01 + orderInfo: + productCode: Рассрочка для партнёра + number: 2023-123-234-3459 ОТ + date: 2023-10-25 + amount: 328400 + returnUrl: + success: https://partner.example.ru/success + failure: https://partner.example.ru/failure + paymentDetails: + vat: true + vatAmount: 1.239857567345E10 + bankDetails: + bankName: "АО «Альфа-Банк», г. Москва" + bankBIC: "044525593" + bankCorrespondentAccount: "30101810200000000000" + recipientINN: "5504036333" + recipientKPP: "783801001" + recipientAccount: "30101810200000000000" + recipientName: АКЦИОНЕРНОЕ ОБЩЕСТВО АЛЬФА-БАНК + income: "12000234" + twoPersonalIncomeTaxesInfo: + retentionSumList: + - date: 2022-05-01 + sum: 58552.25 + - date: 2022-05-01 + sum: 58552.25 + paidSumList: + - date: 2022-05-01 + sum: 58552.25 + - date: 2022-05-01 + sum: 58552.25 + employeesQuantityList: + - date: 2022-05-01 + quantity: 134 + - date: 2022-05-01 + quantity: 134 + fullCostSumList: + - date: 2022-05-01 + sum: 58552.25 + - date: 2022-05-01 + sum: 58552.25 + sellerInventory: + inventorySumAndQuantityList: + - date: 2022-05-01 + quantity: 2 + sum: 9000.25 + - date: 2022-05-01 + quantity: 2 + sum: 9000.25 + vat: + counterparts: + - date: 2022-05-01 + quantity: 346 + purchases: + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + sum: 554000.55 + sales: + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + quantity: 346 + purchases: + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + sum: 554000.55 + sales: + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + sum: 554000.55 + totalTaxBaseList: + - date: 2022-05-01 + sum: 554000.55 + - date: 2022-05-01 + sum: 554000.55 + purchaseAndSaleOperations: + - date: 2022-05-01 + quantity: 554000 + - date: 2022-05-01 + quantity: 554000 + transportedGoodsInfo: + deliveries: + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + - date: 2000-01-23 + transportedGoodsVolumeAndCategoryList: + - volume: 3456.65 + category: Категория груза + - volume: 3456.65 + category: Категория груза + feeList: + - date: 2022-05-01 + sum: 3000000.76 + - date: 2022-05-01 + sum: 3000000.76 + insurancePremiumsInfo: + mandatorySocialInsuranceSumList: + - date: 2022-05-01 + sum: 7579815.57 + - date: 2022-05-01 + sum: 7579815.57 + mandatoryMedicalInsuranceSumList: + - date: 2022-05-01 + sum: 7579815.57 + - date: 2022-05-01 + sum: 7579815.57 + mandatoryPensionInsuranceSurchargeSumList: + - date: 2022-05-01 + sum: 7579815.57 + - date: 2022-05-01 + sum: 7579815.57 + mandatoryPensionInsuranceSumList: + - date: 2022-05-01 + sum: 7579815.57 + - date: 2022-05-01 + sum: 7579815.57 + supplementarySocialSupportSumList: + - date: 2022-05-01 + sum: 7579815.57 + - date: 2022-05-01 + sum: 7579815.57 + procuredGoodsInfo: + categories: + - Категория 1 + - Категория 2 + profitTax: + incomes: + - date: 2022-05-01 + sum: 8.777003919E7 + - date: 2022-05-01 + sum: 8.777003919E7 + costs: + - date: 2022-05-01 + sum: 8.777003919E7 + - date: 2022-05-01 + sum: 8.777003919E7 + totalProfits: + - date: 2022-05-01 + sum: 8.777003919E7 + - date: 2022-05-01 + sum: 8.777003919E7 + delay: + loans: + - duration: 12 + overDueDate: 2022-05-01 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01 + sum: 10000 + goods: + - duration: 12 + overDueDate: 2022-05-01 + sum: 10000 + - duration: 12 + overDueDate: 2022-05-01 + sum: 10000 + sellerQuality: + returnedQuantityList: + - date: 2022-05-01 + quantity: 12 + - date: 2022-05-01 + quantity: 12 + goodsConcentrationLevels: + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + - concentrationLevelOfSum: 23.5 + concentrationLevelOfQuantity: 53.2 + nameOfGood: Товар называется так + sellerRatings: + - date: 2022-05-01 + rating: 3.98 + - date: 2022-05-01 + rating: 3.98 + reasonForRefundList: + - date: 2022-05-01 + reason: Какая-то причина возврата или не выполнения заказа + - date: 2022-05-01 + reason: Какая-то причина возврата или не выполнения заказа + calculationsInformation: + currentInterestsSum: 110687 + currentInterestsAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentFinesAndCategories: + - sum: 20299.1 + category: Категория пени/штрафа + - sum: 20299.1 + category: Категория пени/штрафа + currentTaxesSum: 5016161.68 + sixPersonalIncomeTaxesInfo: + imposedKBKTaxes: + - date: 2022-05-01 + sum: 33346.47 + - date: 2022-05-01 + sum: 33346.47 + retentionPITDateAndSumList: + - date: 2022-05-01 + sum: 247912.19 + factDate: 2022-05-28 + - date: 2022-05-01 + sum: 247912.19 + factDate: 2022-05-28 + paidKBKFines: + - date: 2022-05-01 + sum: 9110687.53 + - date: 2022-05-01 + sum: 9110687.53 + paidKBKTaxes: + - date: 2022-05-01 + sum: 9110687.53 + - date: 2022-05-01 + sum: 9110687.53 + paidKBKInterests: + - date: 2022-05-01 + sum: 9110687.53 + - date: 2022-05-01 + sum: 9110687.53 + factIncomes: + - date: 2022-05-01 + sum: 247912.19 + factDate: 2022-05-28 + - date: 2022-05-01 + sum: 247912.19 + factDate: 2022-05-28 + imposedInterests: + - date: 2022-05-01 + sum: 33346.47 + - date: 2022-05-01 + sum: 33346.47 + imposedFines: + - date: 2022-05-01 + sum: 33346.47 + - date: 2022-05-01 + sum: 33346.47 + transactionsInfo: + minSumTransactionMSB: + - date: 2022-05-01 + sum: 1000.15 + - date: 2022-05-01 + sum: 1000.15 + transactionsMSBSumList: + - date: 2022-05-01 + sum: 1000.15 + - date: 2022-05-01 + sum: 1000.15 + transactionsMSBMaxSumList: + - date: 2022-05-01 + sum: 1000.15 + - date: 2022-05-01 + sum: 1000.15 + transactionsMSBAvgSumList: + - date: 2022-05-01 + sum: 1000.15 + - date: 2022-05-01 + sum: 1000.15 + transactionsMSBQuantityList: + - date: 2022-05-01 + quantity: 15 + - date: 2022-05-01 + quantity: 15 + premiumAccount: + hasPremiumAccount: true + BonusNumbersResponse: {} + successGetUserCompliancePositive: + value: + checkPassed: true + persData: + givenName: Иван + familyName: Иванов + middleName: Иванович + name: Иванов Иван Иванович + birthDate: 1990-01-01 + birthPlace: г. Москва + citizenship: RU + inn: "773342345321" + snils: 112-233-445 95 + identityDocumentName: Паспорт РФ + identityDocumentSeries: "1234" + identityDocumentNumber: "567890" + identityDocumentAuthorityCode: 770-001 + identityDocumentAuthorityName: ОУФМС России по г. Москве + identityDocumentIssueDate: 2015-06-10 + actualAddressDetails: + country: Россия + city: Москва + zip: "101000" + street: Тверская + region: "77" + area: Центральный + localityShortName: "" + town: Москва + streetShortName: ул. + houseNumber: "10" + housingNumber: "1" + apartmentNumber: "45" + successGetUserComplianceNegative: + value: + checkPassed: false + reasons: + - description: Отсутствует подтверждение полной идентификации клиента + - description: Неактуальные данные паспорта + OperationResponseSuccess: + value: + operationId: 22413cd0-11d7-4a1a-826d-a82470c18a83 + ResponeWebhooks: + summary: Пример ответа на получение списка вебхуков + value: + pagination: + offset: 0 + limit: 1000 + totalCount: 2 + items: + - id: f9f8c674-7a2a-4297-bdb8-ddd3013de3a3 + object: ul_transaction_default + enabled: true + organizationIdHash: ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c + callbackUri: https://webhook.partner.ru/api/v1/webhook-events + version: 1 + data: + accounts: + - "40802810401300015422" + - "40802810401300015422" + statusDescriptions: + - cause: consent_revoked + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + RequestPostWebhook: + summary: Пример запроса на создание + value: + object: ul_transaction_default + callbackUri: https://webhook.partner.ru/api/v1/webhook-events + version: 1 + data: + accounts: + - "40802810401300015422" + - "40802810401300015422" + ResponeWebhook: + summary: Пример ответа + value: + id: f9f8c674-7a2a-4297-bdb8-ddd3013de3a3 + object: ul_transaction_default + enabled: true + organizationIdHash: ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c + callbackUri: https://webhook.partner.ru/api/v1/webhook-events + version: 1 + data: + accounts: + - "40802810401300015422" + - "40802810401300015422" + statusDescriptions: + - cause: consent_revoked + description: The webhook is disabled due to the agreement being revoked + in Alfa ID + RequestPutWebhook: + summary: Пример запроса на редактирование + value: + object: ul_transaction_default + callbackUri: https://webhook.partner.ru/api/v1/webhook-events + enabled: true + version: 1 + data: + accounts: + - "40802810401300015422" + - "40802810401300015422" + ReceiptAndPayoutListRequest: + summary: Пример запроса + value: + externalId: f8c1ffe6-696b-4e35-994f-904a9187806d + company: + accountNumber: "40702810201400022055" + requisite: + - payoutId: 54077ca4-5c99-4f08-bf01-795918055df6 + selfemployed: + vatin: "585414307054" + surname: Северный + name: Элемент + patronymic: Оккамович + payoutRequisite: + payoutType: ACCOUNT + byAccount: + accountNumber: "40817810604100001305" + bic: "044525593" + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutTotalAmount: "24.00" + receiptRequisite: + customerVatin: "0483685159" + customerName: Полное наименование Орг № 89727 + incomeType: FROM_LEGAL_ENTITY + operateDate: 2023-01-18T13:36:42.703Z + requestDate: 2023-01-18T13:36:42.703Z + services: + - amount: "23.00" + name: Курьерские услуги + quantity: 1 + receiptTotalAmount: "23.00" + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + signatureType: RSA + ListResponse: + summary: Пример ответа + value: + requestId: 06ec61b1-efda-a019-b6e5-34ee808da1b6 + externalId: a607d9ac-5bfc-dfc1-b8ae-a7aeb9f1d44d + ReceiptListRequest: + summary: Пример запроса + value: + externalId: 6561cb23-8f28-411c-928c-e718d3fd9ac3 + requisite: + - payoutId: 4e85f1d8-3324-45f4-bfe7-72f557c0da9e + selfemployed: + vatin: "252530829203" + surname: Прекрасный + name: Элемент + patronymic: Насреддинович + receiptRequisite: + customerVatin: "0483685159" + customerName: Полное наименование Орг № 89727 + incomeType: FROM_LEGAL_ENTITY + operateDate: 2023-11-19T13:36:42.703Z + requestDate: 2023-11-20T16:40:42.703Z + services: + - amount: "17" + name: Курьерские услуги за период с 2.12.2020-20.12.2020 + quantity: 1 + receiptTotalAmount: "17" + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + signatureType: RSA + CheckSelfemployedStatusAndPayoutListRequest: + summary: Пример запроса + value: + externalId: eb19f3ef-ca6a-4f84-a28f-c6e7b469b486 + company: + accountNumber: "40702810201400022055" + requisite: + - payoutId: b766f52d-f6e6-4a47-bd71-ab332bd0d314 + selfemployed: + vatin: "252530829203" + surname: Прекрасный + name: Элемент + patronymic: Насреддинович + payoutRequisite: + payoutType: ACCOUNT + byAccount: + accountNumber: "40817810110210005303" + bic: "044525593" + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutTotalAmount: "24.00" + receiptRequisite: + receiptId: 200wr5cn4s + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + signatureType: RSA + PayoutListRequest: + summary: Пример запроса + value: + externalId: eb19f3ef-ca6a-4f84-a28f-c6e7b469b486 + company: + accountNumber: "40702810201400022055" + requisite: + - payoutId: b766f52d-f6e6-4a47-bd71-ab332bd0d314 + selfemployed: + vatin: "252530829203" + surname: Прекрасный + name: Элемент + patronymic: Насреддинович + payoutRequisite: + payoutType: ACCOUNT + byAccount: + accountNumber: "40817810110210005303" + bic: "044525593" + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutTotalAmount: "24.00" + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + signatureType: RSA + PayoutListStateResponse: + summary: Пример ответа + value: + pagination: + limit: 1000 + offset: 0 + totalCount: 10000 + requestId: e82331bd-28ac-481b-b7c3-e03673abc20b + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + createdDate: 2023-03-28T08:46:23.462Z + listStatus: NEW + accountNumber: "40702810501300001805" + statementList: + - payoutId: e82331bd-28ac-481b-b7c3-e03673abc20b + selfemployed: + vatin: "112233445566" + surname: Иванов + name: Иван + patronymic: Иванович + payoutRequisite: + payoutType: ACCOUNT + byAccount: + accountNumber: "40817810306050000000" + bic: "044525593" + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + payoutTotalAmount: "10.00" + receiptRequisite: + customerVatin: "5566778899" + customerName: ООО Петуния + incomeType: FROM_LEGAL_ENTITY + operateDate: 2023-03-28T08:46:23.463Z + requestDate: 2023-03-28T08:46:23.463Z + services: + - amount: "10.00" + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + quantity: 1 + receiptTotalAmount: "10.00" + receiptLink: + receiptId: 200wr5cn4s + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + receiptStatus: + status: READY + updatedDate: 2023-03-28T08:46:23.463Z + payoutStatus: + status: READY + updatedDate: 2023-03-28T08:46:23.463Z + errorRecord: + - field: Наименование поля в котором возникла ошибка + message: Описание ошибки + CancelReceiptRequest: + summary: Пример запроса + value: + externalId: f8c1ffe6-696b-4e35-994f-904a9187806d + cancelReceipt: + - vatin: "585414307054" + receipt: + - receiptId: 26o3rf60af + cancelReasonCode: REGISTRATION_MISTAKE + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + signatureType: RSA + CancelReceiptStateResponse: + summary: Пример запроса + value: + pagination: + limit: 100 + offset: 0 + totalCount: 1 + requestId: c2f85d3e-2eba-4e61-9e4e-e535e91ef75f + externalId: 56e68647-1c31-4ea7-a3bd-8b7f79d80b71 + createdDate: 2023-05-04T13:02:46.416183+03:00 + listStatus: SUCCESS + error: {} + statementList: + - receiptId: "123" + cancelReasonCode: REGISTRATION_MISTAKE + status: TECHNICAL_ERROR + errorMessage: Payout not found + PayoutResponse: + summary: Пример ответа + value: + pagination: + limit: 1 + offset: 0 + totalCount: 12000 + payoutsList: + - payoutId: 54077ca4-5c99-4f08-bf01-795918055df6 + vatin: "0483685159" + requestId: fcdf06aa-bc65-4b60-9121-6b4b4e886526 + externalId: f8c1ffe6-696b-4e35-994f-904a9187806d + payerAccountNumber: "40702810001300000050" + createdDate: 2023-06-30T02:41:56.363817+03:00 + payoutRequisite: + payoutType: ACCOUNT + payoutTotalAmount: "24.00" + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810010210029719" + bic: "044525593" + receiptRequisite: + customerVatin: "0483685159" + customerName: Полное наименование Орг № 89727 + incomeType: FROM_LEGAL_ENTITY + operateDate: 2023-06-29T22:46:27.80923+03:00 + requestDate: 2023-04-15T23:07:52+03:00 + services: + - amount: "23.00" + name: Курьерс + quantity: "1" + receiptTotalAmount: "23.00" + receiptLink: {} + receiptStatus: {} + payoutStatus: + status: TECHNICAL_ERROR + PayoutVatinResponse: + summary: Пример ответа + value: + pagination: + limit: 100 + offset: 0 + totalCount: 1 + payoutsList: + - payoutId: ec7e7eaa-7d47-41dc-b26c-183fdfd44413 + vatin: "037630767401" + requestId: 21f8af7a-a474-47ba-8420-ef4fb68bc220 + externalId: ec7e7eaa-7d47-41dc-b26c-183fdfd44413 + payerAccountNumber: "40702810001300000050" + createdDate: 2023-06-29T16:07:33.795049+03:00 + payoutRequisite: + payoutType: ACCOUNT + payoutTotalAmount: "24.00" + byAccount: + purpose: Курьерские услуги за период с 1.12.2020-20.12.2020 + comment: Курьерские услуги за период с 1.12.2020-20.12.2020 + accountNumber: "40817810010210029719" + bic: "044525593" + receiptRequisite: + customerVatin: "037630767401" + customerName: Полное наименование Орг № 89727 + incomeType: FROM_LEGAL_ENTITY + operateDate: 2023-04-03T22:26:50+03:00 + requestDate: 2023-06-29T16:07:33.597443+03:00 + services: + - amount: "23.00" + name: Курьерс + quantity: "1" + receiptTotalAmount: "23.00" + receiptLink: + receiptId: 279iru4gle + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/936144570006/279iru4gle/print + receiptStatus: + status: READY + payoutStatus: + status: READY + updatedDate: 2023-04-03T22:26:50+03:00 + SelfemployedListRequest: + summary: Пример запроса + value: + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + selfemployed: + - personalInformation: + vatin: "112233445566" + surname: Иванов + name: Иван + patronymic: Иванович + phone: "79130000011" + birthDate: 2000-03-02 + birthPlace: Г. Иркутск + citizenship: RU + passport: + series: "6953" + number: "987435" + dateOfIssue: 2022-03-02 + codeOfIssue: 123-321 + authority: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + email: IvanovIvan@mail.ru + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 5f61c6f7-66c1-4820-bcef-197d4420c34f + signatureType: RSA + SelfemployedListStateResponse: + summary: Пример ответа + value: + pagination: + limit: 1000 + offset: 0 + totalCount: 10000 + requestId: e82331bd-28ac-481b-b7c3-e03673abc20b + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + listStatus: NEW + createdDate: 2023-03-28T10:22:08.076Z + selfemployedAccount: + - selfemployed: + personalInformation: + vatin: "112233445566" + surname: Иванов + name: Иван + patronymic: Иванович + phone: "79130000011" + birthDate: 2000-03-02 + birthPlace: Г. Иркутск + citizenship: RU + passport: + series: "6953" + number: "987435" + dateOfIssue: 2022-03-02 + codeOfIssue: 123-321 + authority: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + email: IvanovIvan@mail.ru + idCard: + type: migrationCard + number: "1234567" + dateOfEffective: 2022-03-02 + dateOfExpiry: 2024-03-02 + status: READY + updatedDate: 2023-03-28T10:22:08.076Z + RequestTaxpayerStatusList: + summary: Пример запроса + value: + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + selfemployedVatinList: + - "258200435963" + TaxpayerListStatusResponse: + summary: Пример ответа + value: + pagination: + limit: 1000 + offset: 0 + totalCount: 10000 + requestId: 4e817e78-5876-4608-a873-bcc141454045 + externalId: a607d9ac-5bfc-dfc1-b8ae-a7aeb9f1d44d + taxpayerStatusList: + - vatin: "112233445566" + status: TAXPAYER_BOUND + AccrualAndDebtListStatusRequest: + summary: Пример запроса + value: + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + selfemployedVatinList: + - "258200435963" + AccrualAndDebtListStatusResponse: + summary: Пример ответа + value: + pagination: + limit: 1000 + offset: 0 + totalCount: 10000 + requestId: e82331bd-28ac-481b-b7c3-e03673abc20b + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + accrualList: + - vatin: "112233445566" + status: NEW + taxChargeList: + - amount: "10.00" + dueDate: 2022-03-02 + paidAmount: "10.00" + updatedAt: 2023-03-28T10:05:57.281Z + krsbList: + - debt: 990 + penalty: 0.1 + overpayment: 0 + updatedAt: 2023-03-28T10:05:57.281Z + PaymentDocumentListStatusResponse: + summary: Пример ответа + value: + pagination: + limit: 1000 + offset: 0 + totalCount: 10000 + requestId: 13a5B82A-9B84-5BDA-FBFa-c1ccD95cB540 + externalId: 4feF748b-908F-3f75-20bd-7A96BD7E8aef + paymentDocumentListState: + - vatin: "836656935521" + status: SUCCESS + SelfemployedListResponse: + summary: Пример ответа + value: + pagination: + offset: 0 + limit: 1000 + totalCount: 10000 + selfemployedAccount: + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02 + number: "1234567" + dateOfExpiry: 2024-03-02 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02 + email: IvanovIvan@mail.ru + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23 + status: null + - selfemployed: + birthPlace: Г. Иркутск + address: Иркутская область Г. Иркутск ул. Ленина д.25 кв. 110 + passport: null + phone: "79130000011" + idCard: + dateOfEffective: 2022-03-02 + number: "1234567" + dateOfExpiry: 2024-03-02 + type: migrationCard + personalInformation: + vatin: "112233445566" + patronymic: Иванoвич + surname: Иванов + name: Иван + citizenship: RU + birthDate: 2000-03-02 + email: IvanovIvan@mail.ru + errorRecord: + - field: field + error_description: error_description + - field: field + error_description: error_description + updatedDate: 2000-01-23T04:56:07.000+00:00 + status: null + RequestSelfemployedVatin: + summary: Пример запроса + value: + requestUniqueRights: true + TaxpayerAccountInfoRequest: + summary: Пример ответа + value: + vatin: "112233445566" + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + IncomeForPeriodRequest: + summary: Пример запроса + value: + vatin: "112233445566" + taxPeriodId: "202306" + externalId": e82331bd-28ac-481b-b7c3-e03673abc20b + IncomeV2Request: + summary: Пример запроса + value: + vatin: "112233445566" + offset: 0 + limit: 10 + externalId: e82331bd-28ac-481b-b7c3-e03673abc20b + from: 2023-06-30T00:00:00+03:00 + to: 2023-06-30T23:59:59+03:00 + GetIncomeV2Response: + summary: Пример ответа + value: + receipts: + - totalAmount: 25.04 + customerVatin: customerVatin + partnerCode: partnerCode + incomeType: null + cancelationTime: 2023-06-30T16:17:57.874Z + taxPeriodId: "202306" + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + requestDate: 2023-06-30T16:17:57.874Z + services: + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + receiptId: 200wr5cn4s + operateDate: 2023-06-30T16:17:57.874Z + taxToPay: 1.38 + - totalAmount: 25.04 + customerVatin: customerVatin + partnerCode: partnerCode + incomeType: null + cancelationTime: 2023-06-30T16:17:57.874Z + taxPeriodId: "202306" + link: https://lknpd-adp.gnivc.ru/api/v1/receipt/252530829203/200wr5cn4s/print + requestDate: 2023-06-30T16:17:57.874Z + services: + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + - amount: 10.05 + quantity: 0 + name: Курьерские услуги за период с 1.12.2020-20.12.2020 + receiptId: 200wr5cn4s + operateDate: 2023-06-30T16:17:57.874Z + taxToPay: 1.38 + AgreementPageRequest: + summary: Пример запроса + value: + phone: "79130000011" + activities: + - "17" + regions: + - "40000000" + returnUrl: https://alfabank.ru/ + AgreementPageResponse: + summary: Пример ответа + value: + agreementPageId: 8658d934-9527-413b-b23c-d87bb1e9824a + agreementPageLink: https://alfabank.ru/agreement/97ae89a6-2813-4d4d-a2a6-4a10adba9e1f + ActivitiesResponse: + summary: Пример ответа + value: + - id: "17" + name: Доставка + RegionsResponse: + summary: Пример ответа + value: + - oktmo: "40000000" + name: Санкт-Петербург + SbpBanksResponse: + summary: Пример ответа + value: + - bankName: Газпромбанк + bankId: "100000000001" + CreatePoaResponse: + summary: Пример ответа + value: + requestUuid: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + GetPoaRequestStatusResponse: + summary: Пример ответа + value: + requestUuid: 6ce35d97-f061-4ecf-a333-c1da3d8d4618 + downloadingStatus: COMPLETE + detailedPoa: + number: e0b215fa-78eb-44ad-9fdb-08924ff64131 + inn: "112233445566" + GetPoaStatusResponse: + summary: Пример ответа + value: + id: 9cmCi4vnp5Z832k3Z4YXa1aqYMh8hMw7ZtZE6yP9P2Db + poaNumber: e0b215fa-78eb-44ad-9fdb-08924ff64131 + startDate: 1901-01-01 + endDate: 2099-01-01 + status: ACTIVE + issuerPublicKey: 3066301F06082A85030701010101301306072A85030202240006082A850307010102020343000440D037957D55FB52D5D958E52934C3BEF5C819C3F37CB843D180FCF3C3C777CE92DCB99601F249D2FE3D26BE571FCC67DCDCD740A75D12B5B304C3E5598BFFEFBB + GetAccounts: + summary: Пример ответа + value: + - accountNumber: "40817810306050000000" + isActive: false + - accountNumber: "40817810306053040506" + isActive: true + StatusPENDINGResponse: + summary: PENDING + value: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: PENDING + StatusFAILEDResponse: + summary: FAILED + value: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: FAILED + error: internal_error + error_description: Произошла техническая ошибка. Обратитесь в службу поддержки + и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2 + StatusCOMPLETEResponse: + summary: COMPLETE + value: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: COMPLETE + StatusResultDataResponse: + summary: COMPLETE с результирующими данными + value: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: COMPLETE + resultData: "Данные субъекта не прошли проверку: N05 PBS0023\\nСубъект не\ + \ прошел скоринг и деактивирован в системе.\\n" + BeneficiaryListResponse: + summary: Пример ответа + value: + - beneficiaryId: cba2888c-71ad-4211-9420-a85f6e4c10f9 + isBeneficiary: true + isVpr: false + accountNumber: "40817810306053040506" + type: FL_RESIDENT + personalInformation: + vatin: "112233445566" + firstName: Иван + middleName: Иванович + lastName: Иванов + citizenship: RU + birthDate: 1992-03-02 + birthPlace: г. Москва + snils: "72865174431" + phoneNumber: "79130000011" + email: IvanovIvan@email.ru + addresses: + - type: REGISTRATION_ADDRESS + address: ул. Пушкина 55 + documents: + - type: PASSPORT + serial: "8012" + number: "555777" + issueDate: 2012-03-02 + organization: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + division: 123-321 + isActive: true + - beneficiaryId: 87e33a48-ed80-4493-a66e-7268c9ec4931 + isBeneficiary: true + isVpr: false + accountNumber: "40817810306053040506" + type: UL_RESIDENT + phoneNumber: "78005553535" + email: welcome@email.ru + addresses: + - type: LEGAL_ENTITY_ADDRESS + address: ул. Максима Горького 55 + name: Акционерное общество «Ромашка» + vatin: "1122334455" + ogrn: "7665544332211" + registrationDate: 2012-12-21 + isActive: true + AddFLRequest: + summary: "ФЛ, резидент" + value: + isBeneficiary: true + type: FL_RESIDENT + accountNumber: "40817810306053040506" + personalInformation: + vatin: "112233445566" + firstName: Иван + middleName: Иванович + lastName: Иванов + citizenship: RU + birthDate: 1992-03-02 + birthPlace: г. Москва + snils: "72865174431" + phoneNumber: "79130000011" + email: IvanovIvan@email.ru + addresses: + - type: REGISTRATION_ADDRESS + address: ул. Пушкина 55 + documents: + - type: PASSPORT + serial: "8012" + number: "555777" + issueDate: 2012-03-02 + organization: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + division: 123-321 + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + AddULRequest: + summary: "ЮЛ, резидент" + value: + isBeneficiary: true + type: UL_RESIDENT + accountNumber: "40817810306053040506" + phoneNumber: "78005553535" + email: welcome@email.ru + addresses: + - type: LEGAL_ENTITY_ADDRESS + address: ул. Максима Горького 55 + name: Акционерное общество «Ромашка» + vatin: "1122334455" + ogrn: "7665544332211" + registrationDate: 2012-12-21 + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + RequestResponse: + summary: Пример ответа + value: + requestId: ab9cbb96-360a-4462-a683-955cc29f7f54 + status: PENDING + GetFLResponse: + summary: "ФЛ, резидент" + value: + beneficiaryId: cba2888c-71ad-4211-9420-a85f6e4c10f9 + isBeneficiary: true + isVpr: false + accountNumber: "40817810306053040506" + type: FL_RESIDENT + personalInformation: + vatin: "112233445566" + firstName: Иван + middleName: Иванович + lastName: Иванов + citizenship: RU + birthDate: 1992-03-02 + birthPlace: г. Москва + snils: "72865174431" + phoneNumber: "79130000011" + email: IvanovIvan@email.ru + addresses: + - type: REGISTRATION_ADDRESS + address: ул. Пушкина 55 + documents: + - type: PASSPORT + serial: "8012" + number: "555777" + issueDate: 2012-03-02 + organization: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + division: 123-321 + isActive: true + GetULResponse: + summary: "ЮЛ, резидент" + value: + beneficiaryId: 87e33a48-ed80-4493-a66e-7268c9ec4931 + isBeneficiary: true + isVpr: false + accountNumber: "40817810306053040506" + type: UL_RESIDENT + phoneNumber: "78005553535" + email: welcome@email.ru + addresses: + - type: LEGAL_ENTITY_ADDRESS + address: ул. Максима Горького 55 + name: Акционерное общество «Ромашка» + vatin: "1122334455" + ogrn: "7665544332211" + registrationDate: 2012-12-21 + isActive: true + ChangeFLRequest: + summary: "ФЛ, резидент" + value: + type: FL_RESIDENT + personalInformation: + firstName: Иван + middleName: Иванович + lastName: Иванов + birthDate: 1992-03-02 + birthPlace: г. Москва + phoneNumber: "79130000011" + email: IvanovIvan@email.ru + addresses: + - type: REGISTRATION_ADDRESS + address: ул. Пушкина 55 + documents: + - type: PASSPORT + serial: "8012" + number: "555777" + issueDate: 2012-03-02 + organization: ОВД Иркутской области по Г. Иркутску по Октябрьскому району + division: 123-321 + isActive: true + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + ChangeULRequest: + summary: "ЮЛ, резидент" + value: + type: UL_RESIDENT + phoneNumber: "78005553535" + email: welcome@email.ru + addresses: + - type: LEGAL_ENTITY_ADDRESS + address: ул. Максима Горького 55 + name: Акционерное общество «Ромашка» + registrationDate: 2012-12-21 + isActive: false + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + RequisiteAccountRequest: + summary: Реквизиты счета + value: + type: ACCOUNT_NUMBER + accountNumber: "40817810570000123456" + bik: "123456789" + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + RequisitePhoneRequest: + summary: Номер телефона + value: + type: PHONE_NUMBER + phoneNumber: "79130000011" + bankId: "012345678910" + isMain: false + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + RequisitePanRequest: + summary: Номер карты (токен) + value: + type: CARD_NUMBER + pan: wS7fElYo8VWeJ8KelaJ0XA== + isMain: false + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + RequisiteAccountResponse: + summary: Реквизиты счета + value: + id: 69e7d84f-9a84-4f60-9bde-6797c9b9736f + isMain: true + isActive: true + RequisitePhoneResponse: + summary: Номер телефона + value: + id: 5d645ebf-8f0b-4125-a4e2-2c6a041ae246 + isMain: false + isActive: true + IsActiveRequest: + summary: Признак активности реквизитов + value: + isActive: false + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + IsMainRequest: + summary: Признак основных реквизитов + value: + isMain: false + digestSignatures: + - base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: afc38fe0-6674-e319-4897-4c7f8f55babd + signatureType: rsa + poaNumber: DOVER_CBR_7702235133_20211102_1 + BalanceResponse: + summary: Пример ответа + value: + accountNumber: "40817810306053040506" + beneficiaryId: cba2888c-71ad-4211-9420-a85f6e4c10f9 + date: 2024-01-01 + balance: "10.00" + successAccountsGet: + summary: Получение счетов + value: + accounts: + - mnemonic: moneyway + number: "40817810704980004078" + type: EH + typeDescription: Текущий счёт + status: ACTIVE + dateCreated: 2021-08-23 + balance: + currency: RUR + minorUnits: 100 + holds: 10000 + amount: 50000 + successAccountByNumber: + summary: Получение информации по счёту + value: + mnemonic: moneyway + number: "40817810704980004078" + type: EH + typeDescription: Текущий счёт + status: ACTIVE + dateCreated: 2021-08-23 + balance: + currency: RUR + minorUnits: 100 + holds: 10000 + amount: 50000 + accountRequisitesRurGet: + summary: Получение реквизитов (RUR счёт) + value: + clientInfo: + firstName: Иван + lastName: Иванов + patronymicName: Иванович + accountNumber: "40817810704980004078" + bankName: "АО «Альфа-Банк», г. Москва" + bic: "044525593" + inn: "7728168971" + kpp: "770801001" + correspondentAccountNumber: "30101810200000000593" + accountRequisitesForeignGet: + summary: Получение реквизитов (Валютный счёт) + value: + clientInfo: + firstName: Иван + lastName: Иванов + patronymicName: Иванович + translitFirstName: Ivan + translitLastName: Ivanov + translitPatronymicName: Ivanovic + accountNumber: "40817810704980004078" + bankName: "AO «ALFA-BANK», 27 Kalanchevskaya str., Moscow, 107078" + correspondentBanks: + - correspondentBankAccountNumber: "36310481" + correspondentBankName: "CITIBANK NA, 399 Park Avenue, New York, NY 10043,\ + \ USA" + correspondentSwift: CITIUS33 + successCardsGet: + summary: Получение списка карт + value: + cards: + - cardId: "123731041" + maskedNumber: 458443******3430 + type: ER + typeDescription: RR + title: VISA Rewards PW + status: "0" + issueDate: 2021-11-15T08:28:22+03:00 + account: + number: "40817810605610705598" + expirationDate: "1126" + isPrimary: true + isVirtual: false + isCredit: false + paymentSystem: VISA + state: + isActive: true + isBlocked: false + isClosed: false + GetCardActionsSuccessResponse: + summary: Список доступных действий/задач по заданной карте + value: + actions: + - actionId: CARD_BLOCK + title: Блокировка карты + available: true + CardActionCreateSuccessResponse: + summary: Создание операции блокировки карты + value: + reference: H390506200000003 + auth: SMSPWD + passwordLength: 4 + successTariffsGet: + summary: Получение условий обслуживания + value: + conditions: + cardServiceFee: + fee: 0 + feePeriod: YEARLY + isSalaryCard: false + isCombo: false + successSubscriptionsGet: + summary: Получение информации о подключенных уведомлениях по операциям + value: + subscriptionTariffs: + - id: ONLYSMS + name: SMS + priceAmount: + value: 5900 + currency: RUR + minorUnits: 100 + isSelected: true + isContactPhoneRequired: true + successOperationsHistoryGet: + summary: Получение списка истории операций по набору критериев + value: + operations: + - id: 1220117MOCOIBSR 04461 + dateTime: 2022-01-17T14:47:49.65Z + title: МТС 9166666666 + amount: + value: 100 + currency: RUR + minorUnits: 100 + comment: Перевод за услуги IPTV + mcc: "4899" + category: + id: "00012" + name: "Телефон, интернет, ТВ" + direction: EXPENSE + loyalty: + title: Компенсация за плату услуг Альфа картой + percent: 10 + amount: + value: 100 + currency: RUR + minorUnits: 100 + status: SUCCESS + type: A01 + terminal: + number: "123456789" + name: МТС online + city: Moscow + countryCode: RU + sender: + name: Сидоров Сидор Сидорович + accountNumber: "40817810810210032401" + bankBik: "044525593" + bankName: Альфа Банк + phoneNumber: 79201112222 + maskedCardNumber: 1111XXXXXXXX2222 + recipient: + name: МТС + bankBik: "044525500" + bankName: ООО МТС Банк + phoneNumber: 12223334455 + fee: 50.0 + isAnotherClient: false + cashout: false + successOperationDetailsGet: + summary: Получение информации об операции по индетификатору операции + value: + id: 1220117MOCOIBSR 04461 + dateTime: 2022-01-17T14:47:49.65Z + title: МТС 9166666666 + amount: + value: 100 + currency: RUR + minorUnits: 100 + comment: Перевод за услуги IPTV + mcc: "4899" + category: + id: "00012" + name: "Телефон, интернет, ТВ" + direction: EXPENSE + loyalty: + title: Компенсация за аплату услуг Альфа картой + percent: 10 + amount: + value: 100 + currency: RUR + minorUnits: 100 + status: SUCCESS + type: A01 + terminal: + number: "123456789" + name: МТС online + city: Moscow + countryCode: RU + sender: + name: Сидоров Сидор Сидорович + accountNumber: "40817810810210032401" + bankBik: "044525593" + bankName: Альфа Банк + phoneNumber: 79201112222 + maskedCardNumber: 1111XXXXXXXX2222 + recipient: + name: МТС + bankBik: "044525500" + bankName: ООО МТС Банк + phoneNumber: 12223334455 + fee: 50.0 + isAnotherClient: false + cashout: false + successCreateAccountReport: + summary: Заказ выписки по счету + value: + id: 63d11487bbefcc000184cdfd + date: 2023-01-25T11:37:43.068Z + type: + code: ufr_stmt_physical_vypiska + title: Выписка по счету + status: ENQUEUED + createCreditProductReport: + summary: Заказ выписки по кредиту + value: + id: 63d11df5bbefcc000184ce44 + date: 2023-01-25T12:17:57.831Z + type: + code: ufr_stmt_physical_credit_product + title: Выписка по кредиту + status: ENQUEUED + successCreateAccountBalanceEngReport: + summary: Заказ справки о доступном остатке на англ + value: + id: 63d117cfbbefcc000184ce12 + date: 2023-01-25T11:51:43.103Z + type: + code: ufr_stmt_physical_acc_balance_en + title: О доступном остатке на английском + status: ENQUEUED + successCreateAccountBalanceRurReport: + summary: Заказ справки о доступном остатке на русском + value: + id: 63d118bbbbefcc000184ce24 + date: 2023-01-25T11:55:39.457Z + type: + code: ufr_stmt_physical_acc_balance_rur + title: О доступном остатке на русском + status: ENQUEUED + createClosedCreditsReport: + summary: Заказ справки о закрытых кредитах + value: + id: 63d11ba3bbefcc000184ce41 + date: 2023-01-25T12:08:03.415Z + type: + code: ufr_stmt_physical_closed_credit_sfa + title: Справка о закрытых кредитах + status: ENQUEUED + createCreditInfoReport: + summary: Заказ справки о наличии или отсутствии кредитов + value: + id: 63d11cc8bbefcc000184ce43 + date: 2023-01-25T12:12:56.565Z + type: + code: ufr_stmt_physical_credit_info + title: О наличии или отсутствии кредитов + status: ENQUEUED + successCreateDepositReport: + summary: Заказ справки по депозиту + value: + id: 63d119d1bbefcc000184ce2f + date: 2023-01-25T12:00:17.935Z + type: + code: ufr_stmt_physical_deposit + title: Справка по депозиту + status: ENQUEUED + successLimits: + summary: Получение базовых лимитов клиента + value: + oneTime: + cashWithdrawals: + title: Снятие наличных + limits: {} + transfers: + title: Переводы + limits: + atmTransferCardToAnotherBank: + title: С карты Альфа-Банка в другой банк + max: + value: 30000000 + currency: RUR + minorUnits: 100 + rest: + value: 30000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + atmTransferCardToCardAlfaBank: + title: Между картами Альфа-Банка + max: + value: 60000000 + currency: RUR + minorUnits: 100 + rest: + value: 60000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferBetweenOwnAccounts: + title: Между своими счетами + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToPerson: + title: Клиенту банка + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToSbp: + title: Перевод через СБП + max: + value: 30000000 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferToAny: + title: Перевод в другой банк + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + convertRubToUsd: + title: Конвертация валют + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + payments: + title: Платежи + limits: + paymentsInternetAndMobile: + title: За интернет и мобильный + max: + value: 1500000 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + paymentsTelecom: + title: "За ТВ, телефонию и ЖКУ" + max: + value: 1500000 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + paymentsCommunal: + title: Коммунальные платежи + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsBudget: + title: Платежи в бюджет РФ + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsSBP: + title: Оплата товаров/услуг через СБП + max: + value: 99999999 + currency: RUR + minorUnits: 100 + rest: + value: 0 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + day: + cashWithdrawals: + title: Снятие наличных + limits: {} + transfers: + title: Переводы + limits: + atmTransferCardToAnotherBank: + title: С карты Альфа-Банка в другой банк + max: + value: 100000000 + currency: RUR + minorUnits: 100 + rest: + value: 100000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + atmTransferCardToCardAlfaBank: + title: Между картами Альфа-Банка + max: + value: 200000000 + currency: RUR + minorUnits: 100 + rest: + value: 200000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferBetweenOwnAccounts: + title: Между своими счетами + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToPerson: + title: Клиенту банка + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToSbp: + title: Перевод через СБП + max: + value: 30000000 + currency: RUR + minorUnits: 100 + rest: + value: 30000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferToAny: + title: Перевод в другой банк + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + convertRubToUsd: + title: Конвертация валют + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + payments: + title: Платежи + limits: + paymentsInternetAndMobile: + title: За интернет и мобильный + max: + value: 5000000 + currency: RUR + minorUnits: 100 + rest: + value: 5000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + paymentsTelecom: + title: "За ТВ, телефонию и ЖКУ" + max: + value: 10000000 + currency: RUR + minorUnits: 100 + rest: + value: 10000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + paymentsCommunal: + title: Коммунальные платежи + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsBudget: + title: Платежи в бюджет РФ + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsSBP: + title: Оплата товаров/услуг через СБП + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + month: + cashWithdrawals: + title: Снятие наличных + limits: + atmWithdrawals: + title: Снятие наличных в банкоматах РФ + max: + value: 300000000 + currency: RUR + minorUnits: 100 + rest: + value: 300000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transfers: + title: Переводы + limits: + atmTransferCardToAnotherBank: + title: С карты Альфа-Банка в другой банк + max: + value: 300000000 + currency: RUR + minorUnits: 100 + rest: + value: 300000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + atmTransferCardToCardAlfaBank: + title: Между картами Альфа-Банка + max: + value: 300000000 + currency: RUR + minorUnits: 100 + rest: + value: 300000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferBetweenOwnAccounts: + title: Между своими счетами + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToPerson: + title: Клиенту банка + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + transferToSbp: + title: Перевод через СБП + max: + value: 465000000 + currency: RUR + minorUnits: 100 + rest: + value: 465000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: GENERAL + isPersonal: false + transferToAny: + title: Перевод в другой банк + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + convertRubToUsd: + title: Конвертация валют + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + payments: + title: Платежи + limits: + paymentsInternetAndMobile: + title: За интернет и мобильный + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsTelecom: + title: "За ТВ, телефонию и ЖКУ" + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsCommunal: + title: Коммунальные платежи + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsBudget: + title: Платежи в бюджет РФ + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + paymentsSBP: + title: Оплата товаров/услуг через СБП + max: + value: 99999999999999 + currency: RUR + minorUnits: 100 + rest: + value: 99999999999999 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + type: UNLIMITED + isPersonal: false + successGetUserLimits: + summary: Получение пользовательских лимитов клиента + value: + limits: + - activity: + from: 20-01-2023 + to: 16-11-2023 + validity: wholePeriod + coveredOperations: + - onlineShopping + - allDebits + limits: + single: + value: 10000 + currency: RUR + minorUnits: 1 + max: + value: 20000 + currency: RUR + minorUnits: 1 + rest: + value: 2000000 + currency: RUR + minorUnits: 100 + turnover: + value: 0 + currency: RUR + minorUnits: 100 + id: 186 + created: 2023-01-20 + countriesRestrictions: + restrictionType: all + list: [] + successCreateUserLimit: + summary: Создание пользовательского лимита + value: + id: 62c4f39c5f1503000128a5e3 + successLoyaltyAccountsGet: + summary: Получение бонусных счетов + value: + loyaltyAccounts: + - accountNumber: "1419602531731418" + typeDescription: Лояльность X5 Карты + typeId: "205" + balanceAmount: + value: 100 + currency: RUR + minorUnits: 100 + successLoyaltyTransactionsGet: + summary: Получение бонусных начислений + value: + transactions: + - title: Покупка мороженого + account: "40817810704980004078" + reference: EH + cashbackPercent: 0.5 + cashbackAmount: + value: 100 + currency: RUR + minorUnits: 100 + successAccountCashbackGet: + summary: Получение бонусных счетов + value: + cashbackAccount: + accountNumber: "1419602531731418" + typeDescription: Лояльность X5 Карты + typeId: "205" + balanceAmount: + value: 100 + currency: RUR + minorUnits: 100 + cashbackForecast: + totalActivePeriodAmount: + amount: + value: 100 + currency: RUR + minorUnits: 100 + payOutDate: 2022-02-02 + totalIntermediatePeriodAmount: + amount: + value: 100 + currency: RUR + minorUnits: 100 + payOutDate: 2022-02-02 + cashbackStatistic: + payments: + - period: Июнь + status: PAST + amount: + value: 100 + currency: RUR + minorUnits: 100 + overallCashback: + amount: + value: 100 + currency: RUR + minorUnits: 100 + description: Кешбэк за всё время + CreateFormRequest: + summary: Пример запроса + value: + embossingName: PETROV IVAN + firstName: Иван + lastName: Петров + middleName: Викторович + mobilePhone: "9012345678" + email: example@yandex.ru + passportBirthDate: 1990-09-15 + previousFormId: AAAA16686C43888CE05CCCAC163B298F + sex: m + sopdConfirmed: true + CreateFormResponse: + summary: Данные для оформления заявки на дебетовую карту отправлены + value: + formID: 55A42D1698400C9EE0543863BB4C2866 + draftId: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + cause: NOT_REQUESTED + productType: DC + status: APPROVAL_REJECT + InvalidRequest: + summary: Некорректный запрос + value: + error: invalid_request + error_description: "The request is missing a required parameter, includes\ + \ an unsupported parameter or parameter value, repeats the same parameter,\ + \ uses more than one method for including an access token, or is otherwise\ + \ malformed" + FormNotFound: + summary: Заявка с указанным идентификатором не найдена + value: + error: form_not_found + error_description: The requested form is not found + VerifySmsFormCreation: + summary: Заявка на оформление дебетовой карты создана + value: + formID: 55A42D1698400C9EE0543863BB4C2866 + draftId: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + cause: NOT_REQUESTED + productType: DC + status: SUCCESS + VerifySmsFormCompletion: + summary: Оформление заявки на дебетовую карту завершено + value: + status: SUCCESS + UpgradeRequired: + summary: Данные по заявке устарели + value: + error: conflicting_request + error_description: Conflict of the request with the current state of the server + - form is not in a draft condition + ResendSms: + summary: Повторный запрос SMS для подтверждения создания заявки + value: + formID: 55A42D1698400C9EE0543863BB4C2866 + draftId: 5DCD7E06A44C463781A87CC3302F0E1D + payload: + cause: NOT_REQUESTED + productType: DC + status: SUCCESS + ResendSmsStep2: + summary: Повторный запрос SMS для подтверждения завершения оформления заявки + value: + payload: + cause: NOT_REQUESTED + status: NEED_SMS + CheckDraftSuccess: + summary: Получен статус заявки + value: + formId: 55A42D1698400C9EE0543863BB4C2866 + requestCodeWord: true + requestBrokerageAccount: false + userStatus: + - DT + - FAMILY + ConflictingRequest: + summary: Заявка не находится в состоянии "Черновик" + value: + error: upgrade_required + error_description: Server requests a connection that is not supported by the + client - form data is out of date + DeliveryTypesSuccess: + summary: Получены доступные способы доставки + value: + onlyCourierDelivery: true + courier: + cardAttributes: + unnamedCardEnabled: true + namedCardEnabled: false + cityId: 21 + latitude: 55.659348 + longitude: 37.472996 + offices: + pid: 392 + uuid: 83e92bd6-60cd-4924-91a0-571a635c3244 + mnemonic: MOES + title: ДО «ЮГО-ЗАПАДНАЯ» + address: "пр-кт Вернадского, д.119" + addressOfficial: "197022, г. Санкт-Петербург, Каменноостровский пр-кт, д\ + . 42 Б, лит. А" + cardAttributes: + unnamedCardEnabled: true + namedCardEnabled: false + anyOfficeUnnamedEnabled: false + metro: + id: 1.162 + title: Юго-Западная + distance: 604 + lineId: 1 + lineColor: E42313 + lineName: Сокольническая + clientAvailability: OPENED + embossingEnabled: true + prodType: + - pointone + - pointtwo + - serviceoffice + schedule: + - "пн-пт: 10:00-20:00" + - "сб: 10:00-18:00" + - "вс: выходной" + temporarySchedule: + date: с 10.02.2023 по 12.02.2023 + times: + - "пн-ср: 10:00-18:00" + constraints: + date: 1 сентября + times: c 10:00 до 19:00 + distance: 3441.0 + city: + name: Москва + fiasId: 0c5b2444-70a0-4932-980c-b4dc0d3f02b5 + kladrId: 7700000000000 + TimeSlotsSuccess: + summary: Получены тайм-слоты для курьерской доставки карты + value: + uuid: 07a91616-53e1-4ee1-8045-0544e4590a18 + availableDates: + date: 2023-08-03 + slots: + isAvailable: true + slotFrom: 10:00 + slotTo: 11:00 + express: false + FormConfirmationRequest: + summary: Пример запроса + value: + codeWord: Код1 + isUnnamedCard: true + deliveryUuid: 304ad059-ae73-459c-9195-acf353589657 + currency: RUR + officeDelivery: + obtainingOffice: "392" + courierDelivery: + date: 2023-08-12 + address: "г. Москва, ул. Анохина, д. 9" + comment: Возможно не работает домофон + slotTo: 11:00 + slotFrom: 10:00 + express: true + brokerageAccountRequired: true + FormConfirmationSuccess: + summary: Заявка успешно создана + value: + status: SUCCESS + FormConfirmationNeedSms: + summary: Требуется ввести SMS-код для завершения оформления + value: + status: NEED_SMS + GetAccountsResponseExample: + summary: Пример ответа + value: + Data: + Account: + - accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + status: Enabled + currency: RUB + accountType: Personal + accountDescription: Текущий счет ФЛ (НРБ) + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810704980004078" + name: Имя счета 4078 + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "АО «Альфа-Банк», г. Москва" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "30101810200000000593" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + - accountId: 1123675f-e35a-f529-10f8-e4e4af233d9c + status: Enabled + currency: RUB + accountType: Personal + accountDescription: Текущ.сч.ФЛ.Кредитн.карта (НРБ) + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810304100012280" + name: Текущ.сч.ФЛ.Кредитн.карта (НРБ) + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "АО «Альфа-Банк», г. Москва" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "30101810200000000593" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + - accountId: 1123675f-df00-f037-f4b9-73df2f8108dd + status: Enabled + currency: JPY + accountType: Personal + accountDescription: Альфа счет + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810004980004025" + name: Имя 4025 + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "AO «ALFA-BANK», 27 Kalanchevskaya str., Moscow, 107078" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + - accountId: 1123675f-e92f-fb78-4cfd-f5370e8d8996 + status: Enabled + currency: RUB + accountType: Personal + accountDescription: Ср-ва кл. по опер. с ц.б. и ин.вал. + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810704980004093" + name: Ср-ва кл. по опер. с ц.б. и ин.вал. + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "АО «Альфа-Банк», г. Москва" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "30101810200000000593" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + - accountId: 1123675f-e35a-f529-10f9-2e1920dfd15f + status: Disabled + currency: RUB + accountType: Personal + accountDescription: тест + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810304100012281" + name: тест + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "АО «Альфа-Банк», г. Москва" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "30101810200000000593" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + GetAccountResponseExample: + summary: Пример ответа + value: + Data: + Account: + - accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + status: Enabled + currency: RUB + accountType: Personal + accountDescription: Текущий счет ФЛ (НРБ) + AccountDetails: + - schemeName: RU.CBR.BBAN + identification: "40817810704980004078" + name: Имя счета 4078 + Owner: + name: Владимир Александрович Медведев + Identification: + schemeName: RU.CBR.TXID + identification: "799069378370" + mobileNumber: "79114587744" + countryOfResidence: RU + cityOfBirth: Санкт-Петербург + birthDate: 1963-02-25T00:00:00Z + PostalAddress: + addressType: Postal + addressLine: + - "109156, РОССИЯ, Краснодарский край, Краснодарский район, Красно\ + дар, ул. Казачья, д. 46-41, 25" + streetName: Казачья + buildingNumber: 46/41-27 + postCode: "350002" + townName: Краснодар + countrySubDivision: Краснодарский край + country: AF + Servicer: + name: "АО «Альфа-Банк», г. Москва" + BankIdentification: + - schemeName: RU.CBR.BIC + identification: "044525593" + OrganizationIdentification: + - schemeName: RU.CBR.TXID + identification: "7728168971" + - schemeName: RU.CBR.TAXT + identification: "770801001" + CorrespondentAccount: + schemeName: RU.CBR.BBAN + identification: "30101810200000000593" + PostalAddress: + addressType: Residential + addressLine: + - "107078, г. Москва, ул. Каланчевская, д. 27" + streetName: Каланчевская + buildingNumber: "27" + postCode: "107078" + townName: Москва + country: RU + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + BalancesResponseExample: + summary: Пример ответа + value: + Data: + Balance: + - accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + type: ClosingAvailable + Amount: + amount: "240.00" + currency: RUB + creditDebitIndicator: Credit + dateTime: 2024-08-21T08:03:49.620928445Z + CreditLine: [] + - accountId: 1123675f-e35a-f529-10f8-e4e4af233d9c + type: ClosingAvailable + Amount: + amount: "16000.00" + currency: RUB + creditDebitIndicator: Debit + dateTime: 2024-08-21T08:03:49.621057689Z + CreditLine: [] + - accountId: 1123675f-df00-f037-f4b9-73df2f8108dd + type: ClosingAvailable + Amount: + amount: "0.00" + currency: JPY + creditDebitIndicator: Debit + dateTime: 2024-08-21T08:03:49.621132752Z + CreditLine: [] + - accountId: 1123675f-e92f-fb78-4cfd-f5370e8d8996 + type: ClosingAvailable + Amount: + amount: "2400.00" + currency: RUB + creditDebitIndicator: Debit + dateTime: 2024-08-21T08:03:49.621222492Z + CreditLine: [] + - accountId: 1123675f-e35a-f529-10f9-2e1920dfd15f + type: ClosingAvailable + Amount: + amount: "50.00" + currency: RUB + creditDebitIndicator: Debit + dateTime: 2024-08-21T08:03:49.621307386Z + CreditLine: [] + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + BalanceResponseExample: + summary: Пример ответа + value: + Data: + Balance: + - accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + type: ClosingAvailable + Amount: + amount: "240.00" + currency: RUB + creditDebitIndicator: Credit + dateTime: 2024-08-21T08:03:49.620928445Z + CreditLine: [] + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + GetTransactionsResponseExample: + summary: Пример ответа + value: + Data: + Transaction: + - transactionId: 1220618MOCOIBSR 00789 + accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + creditDebitIndicator: Debit + status: AcceptedSettlementCompleted + BankTransactionCode: + code: "00012" + bookingDateTime: 2022-03-18T18:03:02.681Z + groupId: "00012" + Amount: + amount: "1.00" + currency: RUR + - transactionId: 1220311MOCOIBSR 06371 + accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + creditDebitIndicator: Debit + status: AcceptedSettlementCompleted + BankTransactionCode: + code: "00012" + bookingDateTime: 2022-03-22T14:23:35.483Z + groupId: "00012" + Amount: + amount: "100.00" + currency: RUR + - transactionId: 1220310MOCOIBSR 05639 + accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + creditDebitIndicator: Debit + status: AcceptedSettlementCompleted + BankTransactionCode: + code: "00025" + bookingDateTime: 2022-03-30T12:53:37.892Z + groupId: "00025" + Amount: + amount: "1.00" + currency: RUR + Links: + self: https://sb.example.ru/v1.3/example + GetCardsResponseExample: + summary: Пример ответа + value: + Data: + PaymentCard: + - accountId: 1123675f-e7ce-faca-faa4-793d09face73 + paymentCardId: "129600634" + paymentCardType: credit + paymentCardName: Visa Gold PayWave + PaymentCardData: + PAN: "0596" + expiryDate: 12/2028 + cardStatus: blocked + effectiveDate: 06/2022 + cardScheme: VISA + designUrl: "https://online.alfabank.ru/cards-images/cards/CZ/images?layers=BACKGROUND,LOGO,PAYMENT_SYSTEM&width=%d" + - accountId: 1123675f-ec2c-f42f-b2a5-a19202b80883 + paymentCardId: "129600637" + paymentCardType: debit + paymentCardName: MIR + PaymentCardData: + PAN: "0597" + expiryDate: 12/2028 + cardStatus: pending + effectiveDate: 06/2022 + cardScheme: MIR + designUrl: "https://online.alfabank.ru/cards-images/cards/CZ/images?layers=BACKGROUND,LOGO,PAYMENT_SYSTEM&width=%d" + - accountId: 1123675f-ec2c-f42f-b2a5-a19202b80884 + paymentCardId: "129600638" + paymentCardType: debit + paymentCardName: MIR + PaymentCardData: + PAN: "0599" + expiryDate: 12/2028 + cardStatus: active + effectiveDate: 06/2022 + cardScheme: MIR + designUrl: "https://online.alfabank.ru/cards-images/cards/CZ/images?layers=BACKGROUND,LOGO,PAYMENT_SYSTEM&width=%d" + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + GetCardResponseExample: + summary: Пример ответа + value: + Data: + PaymentCard: + - accountId: 1123675f-e92f-fb78-4cee-5f6e93450bb5 + paymentCardId: "129600634" + paymentCardType: credit + paymentCardName: Visa Gold PayWave + PaymentCardData: + PAN: "0596" + expiryDate: 12/2028 + cardStatus: blocked + effectiveDate: 06/2022 + cardScheme: VISA + designUrl: "https://online.alfabank.ru/cards-images/cards/CZ/images?layers=BACKGROUND,LOGO,PAYMENT_SYSTEM&width=%d" + Links: + self: https://sb.example.ru/v1.3/example + Meta: + totalPages: 1 + paymentUrlsOneTimeUseRequest: + summary: Пример запроса + value: + client: + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: 214 + name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + ttl: 4320 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: null + takeTax: true + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + paymentUrlsOneTimeUseResponse: + summary: Пример ответа + value: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + qrcType: ONETIME + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + takeTax: true + taxAmount: 200000 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + lastPayment: null + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + registrationDate: 2022-01-10T12:33:25Z + expirationDate: 2022-05-26T09:09:32Z + paymentUrlsReusableRequest: + summary: Пример запроса + value: + client: + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: 214 + name: Ссылка для ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: null + takeTax: true + taxAmount: 200000 + paymentUrlsReusableResponse: + summary: Пример ответа + value: + qrcId: AO1000670LSS7DN18SJQDNP4B05KLJL2 + payload: https://b2b.cbrpay.ru/AO1000670LSS7DN18SJQDNP4B05KLJL2 + name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + qrcType: REUSABLE + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + takeTax: true + taxAmount: 200000 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + lastPayment: null + uip: null + registrationDate: 2022-05-26T09:09:32Z + expirationDate: null + registerPaymentUrlsRequest: + summary: Пример запроса + value: + client: + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: 214 + paymentUrls: + - name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + qrcType: ONETIME + ttl: 4320 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: https://exampletsp.io/qwertyui + takeTax: true + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + payerInn: "3664069397" + getPaymentUrls: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + paymentUrls: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + qrcType: ONETIME + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + takeTax: true + taxAmount: 200000 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + lastPayment: + amount: 1000000 + taxAmount: 200000 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payerAccount: "40702810901400001130" + currency: RUR + timestamp: 2022-05-26T09:09:32Z + payerInfo: + name: OOO Ромашка + inn: "3664069397" + bik: "044525593" + accountType: BBAN + bankName: АО "АЛЬФА-БАНК" + bankCorrAccount: "30101810200000000593" + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + registrationDate: 2022-01-10T12:33:25Z + expirationDate: 2022-05-26T09:09:32Z + updateStatusPaymentUrlsRequest: + summary: Пример запроса + value: + client: + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: 214 + paymentUrls: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + isActive: true + getPaymentUrlsResponse: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + status: COMPLETE + paymentUrls: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payload: https://b2b.cbrpay.ru/AD1000038AQ1FG409KGACUQU5QRSH3FM + name: Ссылка для оплаты ИП Иванов И.П. + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + ttl: 4320 + qrcType: ONETIME + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + redirectUrl: https://exampletsp.io/qwertyui + takeTax: true + taxAmount: 200000 + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAADXJAK3AAAABmJLR0QA/wD...YII= + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + payerInn: "3664069397" + registrationDate: 2022-01-10T12:33:25Z + expirationDate: 2022-01-13T12:33:25Z + registrationStatus: REGISTERED + errorDescription: "Возникла ошибка при регистрации QR со стороны НСПК: {Т\ + екст ошибки от НСПК}." + getPaymentDataByQRc: + summary: Пример ответа + value: + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + qrcType: ONETIME + legalId: LF0000000001 + legalName: ООО "Кофейня у Артёма" + memberId: "100000000001" + brandName: Кофейня у Артёма + payeeAccount: "40702810100010000001" + merchantId: MF0000000001 + amount: 1000000 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + address: "г. Воронеж, ул. Лисюкова, д.5, стр.1" + mcc: "4122" + fraudScore: "0000000000000000" + inn: "4285733785" + redirectUrl: https://exampletsp.io/qwertyui + agentId: A00000000001 + takeTax: true + taxAmount: 200000 + uip: 281000670LSS7DN18SJQDNP4B05KLJL2 + getIncomingPayments: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + payments: + - qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + amount: 1000000 + taxAmount: 200000 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + payeeAccount: "40702810901400001130" + payerAccount: "40702810901400001289" + currency: RUR + timestamp: 2022-05-26T09:09:32Z + payerInfo: + name: OOO Ромашка + inn: "911006876365" + bik: "044525593" + accountType: BBAN + bankName: АО "АЛЬФА-БАНК" + bankCorrAccount: "30101810200000000593" + recipientInfo: + name: OOO Ромашка + inn: "911006876365" + bik: "044525593" + bankName: АО "АЛЬФА-БАНК" + bankCorrAccount: "30101810200000000593" + getOutgoingPaymentsResponse: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + payments: + - outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + nspkTransactionId: B467FC50C59A469A9898AB7B05EE3F07 + status: COMPLETE + amount: 1000000 + taxAmount: 200000 + currency: RUR + payerAccount: "40702810901400001130" + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + timestamp: 2022-05-26T09:09:32Z + commission: 100 + payerInfo: + name: OOO Ромашка + inn: "911006876365" + bik: "044525593" + accountType: BBAN + bankName: АО "АЛЬФА-БАНК" + bankCorrAccount: "30101810200000000593" + recipientInfo: + name: OOO Ромашка + inn: "911006876365" + bik: "044525593" + bankName: АО "АЛЬФА-БАНК" + bankCorrAccount: "30101810200000000593" + executeOneStepOutgoingPaymentRequest: + summary: Пример запроса + value: + client: + b2bClientId: 021be5ed-6312-4982-a4e9-2a2cc44bc88c + partnerId: 214 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + payerAccount: "40702810100010000001" + amount: 1000000 + paymentPurpose: Оплата по договору №123456789 от 01.09.2001 + takeTax: true + taxAmount: 200000 + digestSignatures: + - base64Encoded: HlaeIHXXEcGT1bFxo1NlpAzpr+kJ2IQrcxVdvDTep6xjsmD1FDb+6NIyLT+/T24S0mPfVCU75sieOMt71TBS7w== + certificateUuid: 61000366d11e143acbc03a56d70001000366d1 + signatureType: RSA + poaNumber: null + executeOneStepOutgoingPaymentResponse: + summary: Пример ответа + value: + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + status: COMPLETE + commission: 100 + outgoingPaymentStatusResponse: + summary: Пример ответа + value: + outgoingPaymentId: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + qrcId: AD1000038AQ1FG409KGACUQU5QRSH3FM + status: COMPLETE + merchantResponse: + summary: Пример ответа + value: + merchantId: MF0000000001 + errorBadRequest: + summary: Ошибка + value: + detail: Некоторые обязательные поля отсутствуют или имеют неверный формат + instance: /path + status: 400 + title: Неверные параметры запроса + type: BAD_REQUEST + errorBadCredentials: + summary: Ошибка + value: + detail: "Неверные логин или пароль, либо устаревший токен" + instance: /path + status: 401 + title: Ошибка аутентификации + type: BAD_CREDENTIALS + authorizationException: + summary: Ошибка + value: + detail: У пользователя недостаточно прав для выполнения операции + instance: /path + status: 403 + title: Доступ запрещён + type: AUTHORIZATION_EXCEPTION + notFoundException: + summary: Ошибка + value: + detail: Указанный объект не существует + instance: /path + status: 404 + title: Ресурс не найден + type: NOT_FOUND + tooManyRequestsException: + summary: Ошибка + value: + detail: Превышено количество запросов за заданный интервал времени + instance: /path + status: 429 + title: Слишком много запросов + type: TOO_MANY_REQUESTS + internalServerErrorException: + summary: Ошибка + value: + detail: При обработке запроса произошла непредвиденная ошибка + instance: /path + status: 500 + title: Внутренняя ошибка сервера + type: INTERNAL_SERVER_ERROR + timeoutException: + summary: Ошибка + value: + detail: Попробуйте выполнить запрос позже + instance: /path + status: 503 + title: Сервис временно недоступен + type: "-" + PaymentsSearchBody: + summary: Пример запроса на поиск платежей по qr кодам + value: + qrIds: + - EX1B006EL9Q5HUTK9VR9PHM322T2ALQN + paymentInfo: + summary: Пример ответа + value: + - account: 40702810601990021865 + amount: 1000 + currency: RUB + operationDate: 2019-08-24T14:15:22Z + paymentId: a40e0714-c5c2-476b-a444-3578edfcbc2a + paymentStatus: IN_PROGRESS + qrId: EX1B006EL9Q5HUTK9VR9PHM322T2ALQN + ReusableLinkBody: + summary: Пример запроса многоразовой ссылки + value: + account: 40702810601990021865 + amount: 1000 + currency: RUB + merchantId: MF0000000001 + paymentPurpose: 1C test payment link + redirectUrl: http://example.ru + takeTax: true + totalTaxAmount: 100 + oneTimeLinkBody: + summary: Пример запроса одноразовой ссылки + value: + account: 40702810601990021865 + amount: 1000 + currency: RUB + merchantId: MF0000000001 + orderId: a00e000-c0c0-006b-a000-3008etrsbc2a + paymentPurpose: 1C test payment link + qrTtl: 1000 + redirectUrl: http://example.ru + takeTax: true + totalTaxAmount: 100 + uip: uniqueId + getPhonePaymentReportResponse: + summary: Пример ответа + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + payments: + - account: "40702810401300003178" + inn: "0352417325" + transactionId: "3389" + sequence: azapov100-frod-1 + payPackage: "5592" + nspkTransactionId: A3137112354541010000050011000101 + nspkBankName: ПИР Банк + nspkName: + last: Иванов + first: Иван + middle: Иванович + nameCheck: true + name: + last: Иванов + first: Иван + middle: Иванович + eqTrnId: C31170523000000X + orderInfo: + number: "51" + date: 2023-08-09T15:18:36.556Z + recipientAccount: "40817495834383110206" + recipientBic: "044525491" + phone: "0079086010338" + amount: 10007.03 + feeAccount: "40702810701300003179" + feeAmount: 1.05 + createDate: 2023-05-17T14:22:40.974Z + modifyDate: 2023-05-17T14:24:58.078Z + nspkStatus: ACWP + addPhonePaymentRequest: + summary: Пример запроса + value: + signedBody: CORRECT_SIGNED_BODY + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + inn: "0352417325" + account: "40702810401300003178" + total: 10007.03 + nameCheck: true + payments: + - name: + last: Иванов + first: Иван + middle: Иванович + amount: 100.53 + nspkBankId: 1crt88888881 + phone: "0079086010338" + sequence: azapov100-frod-1 + paymentDescription: "{AZAPOV44110} azapov22 (AZ114455)" + ric: 1 + addPhonePaymentResponse: + summary: Пример ответа + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + payPackage: "5593" + payments: + - nameCheck: true + name: + last: Иванов + first: Иван + middle: Иванович + amount: 10007.03 + feeAmount: 1.05 + transactionId: "3390" + phone: "0079086010338" + sequence: azapov100-frod-1 + createDate: 2023-05-18T08:21:00.520824Z + paymentDescription: "Перевод СБП.{AZAPOV44110} azapov22 (AZ114455)" + ric: 1 + addPhonePaymentCheckRequest: + summary: Пример запроса + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + nameCheck: true + payments: + - amount: 10007.03 + nspkBankId: 1crt88888881 + phone: "0079056010339" + name: + last: Иванов + first: Иван + middle: Иванович + addPhonePaymentCheckResponse: + summary: Пример ответа + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + checkId: "305" + getPhonePaymentCheckStatusResponse: + summary: Пример ответа + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + payments: + - amount: 10007.03 + nspkBankId: 1crt88888881 + nspkName: + last: Иванов + first: Иван + middle: Иванович + nameCheck: true + name: + last: Иванов + first: Иван + middle: Иванович + phone: "0079056010339" + status: ALLOWED + getBanksResponse: + summary: Пример ответа + value: + - bankId: "100000000001" + bankName: Газпромбанк + getClientInnResponse: + summary: Пример ответа + value: + client: + b2cClientId: 6abd7050-6aea-4fb1-90cd-0e1d8fecb1e4 + partnerId: 214 + inn: "0283988847" + successCreditOffersGet: + summary: Список кредитных предложений + value: + offers: + - id: "70001101781" + title: Кредит на любые цели + webViewUrl: https://alfabank.ru/mobile-offers/web/.../?isWebView=true&fromCurrent=true + creditProduct: + creditInfo: + rate: 9.99 + period: 12 + cardInfo: + gracePeriod: 13 + limit: 2.576E8 + currency: RUR + GetStatisOrDynamicQRc: + summary: Пример запроса + value: + termNo: "30000600" + amount: 10000 + currency: RUR + qrcType: "02" + ttl: 10 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + subscriptionPurpose: Подписка на оплату интернета 500р./мес. + redirectUrl: https://exampletsp.io/qwertyui + GetQRcResponse: + summary: Пример запроса + value: + termNo: "30000600" + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payrrn: "000000020512" + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + status: CREATED + GetQRcStatusResponse: + summary: Пример запроса + value: + creditDatePos: 2022-12-19 + termNo: "30000600" + amount: 10000 + currency: RUR + payrrn: "000000020512" + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + status: ACWP + trxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + trxDT: 2022-12-19T07:40:28Z + GetQRcSubscriptionRequest: + summary: Пример запроса + value: + termNo: "30000600" + subscriptionPurpose: Подписка на оплату интернета 500р./мес. + ttl: 4320 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + redirectUrl: https://exampletsp.io/qwertyui + GetQRcSubscriptionResponse: + summary: Пример запроса + value: + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + payrrn: "000000020512" + PaymentFromBindedAccountRequest: + summary: Пример запроса + value: + termNo: "30000600" + amount: 10000 + currency: RUR + paymentPurpose: Назначение платежа + ttl: 4320 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + redirectUrl: https://exampletsp.io/qwertyui + subscriptionToken: 70LSS7DN18SJQRS10006DNPKLJL24B05 + senderMemberId: "100000000001" + messageId: 123Rersal_Num567 + PaymentFromBindedAccountResponse: + summary: Пример запроса + value: + termNo: "30000600" + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + image: iVBORw0KGgoAAAANSUhEUgAABEoAAARKCAIAAAQA/w…...YII + payrrn: "000000020512" + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + QRcRefundRequest: + summary: Пример запроса + value: + termNo: "30000600" + payrrn: "000000020512" + qrcId: AD100074066RHM939FE9OQKR0TQ63HB6 + originalTrxId: A003610425360300b4ubOp6511E4F998 + originalTrxDT: 2022-12-19T07:40:28Z + amount: 10000 + currency: RUR + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + messageId: 123Rersal_Num567 + QRcRefundResponse: + summary: Пример запроса + value: + termNo: "30000600" + amount: 10000 + currency: RUR + payrrn: "000000020512" + trxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + trxDT: 2022-12-19T07:40:28Z + messageId: 123Rersal_Num567 + GetQRcRefundStatusResponse: + summary: Пример запроса + value: + termNo: "30000600" + batchId: "1738" + amount: "10000" + url: http://10.8.18.33:9017/sbp-payment/agent/status + originalQRcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + originalTrxId: X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2 + payerId: '*******5526' + status: ACWP + trxId: 1SA32XD5F6G78J9K0HC4S5C6D4V7D5J2 + trxDT: 2020-07-28T11:45:31Z + CashQRcsRegistrationRequest: + summary: Пример запроса + value: + mediaType: image/png + width: "200" + height: "200" + redirectUrl: https://exampletsp.io/qwertyui + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + CashQRcsRegistrationResponse: + summary: Пример запроса + value: + termNo: "30000600" + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + payload: https://qr.nspk.ru/AS1000670LSS7DN18SJQDNP4B05KLJL2?type=01&bank=100000000001&sum=100739&cur=RUB&crc=C08B + status: CREATED + image: + mediaType: image/png + content: iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAArvElEQVR4Xu2d/bOvVXne/ + /B2Pwbvw1OqlrAAAAAElFTkSuQmCC + CashQRcsActivationRequest: + summary: Пример запроса + value: + amount: 10000 + currency: RUR + paymentPurpose: "Капучино 300 мл 1 шт., булочка 1 шт." + ttl: 5 + queryData: + notificationUrl: http://10.8.18.33:9017/sbp-payment/agent/status + CashQRcsActivationResponse: + summary: Пример запроса + value: + termNo: "30000600" + paramsId: AP5GK3L276DN8PDR8ON1LF4RVOL44444 + qrcId: AS1000670LSS7DN18SJQDNP4B05KLJL2 + amount: 10000 + currency: RUR + paymentPurpose: "Капучино 300 мл 1 шт., булочка 1 шт." + payrrn: "000000020512" + Request: + summary: Пример запроса + value: + applicationId: 7421w6f13a01983593e8dffb71fa6d15 + applicationCreatedAt: 2000-01-23T04:56:07.000+00:00 + registryNumber: "1" + registryCreatedAt: 2000-01-23T04:56:07.000+00:00 + currency: RUR + contractNumber: 005V4Z + bic: "044525593" + rowsCount: "1" + organization: + fullname: Общество с ограниченной ответственностью Тест Альфа-Линк ЗУП + country: RU + address: Москва + inn: "0178827953" + accountNumber: "40702810200000000083" + employees: + - npp: "1" + lastName: Григорьев + firstName: Вениамин + middleName: Федосьевич + bankBranchCode: "0000" + bankBranchOfficeCode: "0000" + birthDate: 1993-02-21 + sex: M + position: Бухгалтер + salaryCurrencyCode: "643" + resident: "true" + citizenship: РОССИЯ + populationCategory: "207" + mobilePhone: "9054823041" + mobileBank: "2" + bkiSharingAllowed: "false" + personnelNumber: 0000-00114 + employmentDate: 2022-04-05 + salaryAmount: "30000" + paymentDate: 2022-01-05 + contactPhone: "79054823041" + cardInfo: + type: VISA + currencyCode: "643" + embossedText: + firstName: V + lastName: GRIGOREV + salutation: MR + salaryType: "0" + identityDocument: + typeName: Паспорт гражданина РФ + typeCode: "21" + series: 79 96 + number: "380515" + issueDate: 2013-04-19 + issuerName: ТП УФМС РОССИИ ПО Г МОСКВА В ОДЕССКОМ РАЙОНЕ + issuerCode: 550-025 + birthPlace: + regionFull: Москва + regionShort: МСК + districtFull: Москва + districtShort: МСК + cityFull: Москва + cityShort: МСК + locationFull: Москва + locationShort: МСК + GetClientSubscriptions: + summary: Список подписок клиента + value: + - serviceCode: RISK_EVENT + state: DISABLED + activatedAt: 2024-09-17T13:54:37.789+03:00 + nextFeeAt: null + disabledAt: 2024-10-01 + clientDisabledAt: 2024-09-17 + extendedState: REPLACED + - serviceCode: RISK_EVENT + state: ACTIVE + activatedAt: 2024-09-17T13:55:20.506+03:00 + nextFeeAt: 2024-11-01 + disabledAt: null + clientDisabledAt: null + extendedState: ACTIVE + ErrorScope: + summary: "У пользователя нет прав на использование запрашиваемого сервиса, д\ + оступ к которому не предусмотрен настройками scope" + value: + error: insufficient_scope + error_description: The request requires higher privileges than provided by + the access token + NotEnoughRightsForOperation: + summary: У пользователя нет прав на операцию + value: + error: permission_error + error_description: User doesn't have enough rights + DeliveryPageResponseExample: + summary: Пример DeliveryPageResponse + value: + pagination: + offset: 10 + limit: 5 + totalCount: 4901 + items: + - externalId: bf1d1b2f-9ebe-4bf1-8b8f-6f6f6f6f6f6f + productCode: CC + smartRepeated: false + productionTypeCode: Неименная + creationDate: 2025-01-01T00:00:00Z + deliveryDate: 2025-01-15T00:00:00Z + slotFrom: 10:00 + slotTo: 12:00 + statusCode: В работе + clientFio: Иванов И. И. + regionName: Москва + cityName: Москва + deliveryAddress: Ленина 45 + courierFio: Иванов И. И. + viewCard: MIR Classic PW Ins + clientSES: false + comment: Комментарий + brokerageAccountRequired: false + processType: Детский банк. ИА Родитель + Ребёнок + documents: + - Паспорт + ComplianceResponse: + summary: Результат прохождения проверки клиентом + value: + result: true + StatusResponse: + summary: Статус проверяемого документа + value: + status: RECEIVED + CreatePaymentRequest: + summary: Запрос для сохранения платежного поручения + value: + externalId: 0521cc44-ae0f-4e73-9b16-a1630d50e444 + principalInfo: + name: ООО Виктория + inn: "7707083893" + kpp: "773601001" + creditorInfo: + name: ООО Кредитор + inn: "7707083893" + kpp: "773601001" + ogrn: "1027700132195" + bankName: Банк Пример + bankBIC: "044525225" + bankCorrAccountNumber: "30101810400000000225" + accountNumber: "40702810500000000001" + orderType: BUDGET + compensationPeriod: "365" + paymentPurpose: Оплата за услуги + currencyCode: RUB + monetaryClaimAmount: 150077.88 + monetaryClaimId: claim-123 + contractNumber: "12345" + contractDate: 2023-05-10 + fixedRatePercentage: 5.5 + floatRatePercentage: 1.25 + paymentPriority: "5" + payerStatus: "101" + accrualUniqueId: 22-1234567890 + taxPaymentCode: "106" + taxPeriod: "2021" + baseDocumentType: Счет + baseDocumentDate: 2023-04-01 + kbk: "18210102010011000110" + oktmo: "45384000" + SavePaymentResponse: + summary: Ответ на сохранение платежного поручения + value: + externalId: f47ac10b-58cc-4372-a567-0e02b2c3d479 + paymentId: h7d6c70b-5d5c-4542-n207-4g83bj45u579 + CreateRegisterRequest: + summary: Запрос для создания реестра платежных поручений + value: + totalSum: 100000.01 + plannedExecutionDate: 2024-02-15 + paymentIds: + - 24970b11-0bc0-43ab-8087-a8f3d0fe91cf + - h7d6c70b-5d5c-4542-n207-4g83bj45u579 + SaveRegisterResponse: + summary: Ответ на сохранение реестра платежных поручений + value: + id: 76ec6909-dacd-47af-a71d-9db02a3679a7 + file: SGVsbG8sIFdvcmxkIQ== + registerNumber: 13791 + SignRegisterRequest: + summary: Запрос для подписания реестра платежных поручений + value: + registerId: 76ec6909-dacd-47af-a71d-9db02a3679a7 + digestSignatures: + base64Encoded: SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA= + certificateUuid: 22a6dd81-103a-4d3a-8e9b-0ba4b527f5f6 + SignRegisterResponse: + summary: Ответ на подписание реестра платежных поручений + value: + message: The registry has been successfully signed and sent for funding + UpdateOrderResponse: + summary: Пример ответа при изменение информации о статусе заказа + value: + quantity: 0 + orderId: ST1057RQKDD + partnerName: ST + status: L + CreateOrderResponse: + summary: Пример ответа при создании заказа на списание лимитов + value: + quantity: 5 + orderId: ST1057RQUDD + partnerName: ST + createdAt: 2024-01-11T23:19:09.224 + GetBalanceResponse: + summary: Пример ответа при получении доступных лимитов клиента + value: + customerSP: A1 + quantity: 10 + CreateLoungeReportRequest: + summary: "Пример входящего CreateLoungeReportRequest при передачи факта посе\ + щения БЗ, vip-lounge, пользование услугой fasttrack" + value: + id: 35105768-d48e-48cd-8894-71be35692ff8 + alfaData: + userId: 35105768-d48e-48cd-8894-71be35692ff8 + orderId: ST00000001 + count: + request: 4 + adult: 2 + child: 1 + baby: 1 + category: BUSINESS_LOUNGE + usingArea: ALFA + requestDateTime: 2025-01-01T18:00:00.000Z + eventDateTime: 2025-01-01T18:00:00.000Z + service: + id: 35105768-d48e-48cd-8894-71be35692ff9 + name: VIP Lounge Service + transportHub: Sheremetyevo International Airport + country: Russia + type: GENERAL + travelType: INTERNATIONAL + price: + total: 50000 + adult: 30000 + child: 15000 + baby: 5000 + transactionType: FREE + eventStatus: CREATED + LoungeReportResponse: + value: + createdId: 678f435884171b4548c8b59c + getInitialPlacementListResponse: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 1 + items: + - title: АЛЬФА-БАНК + subtitle: Структурная облигация + description: Участие от 10 000Р + icon: https://testdfa.alfabank.ru:9010/dfa/icons/750ad7ea-3158-4966-afab-643ae3f8cd7f + background: '#36363A' + placementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + buyPlacementLink: https://testdfa.alfabank.ru/retail-investor/webview/dfa/buy?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + buyPlacementOneLink: https://test-alfa-mobile.alfabank.ru/mobile/goto/dfa_id_buy_dc?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + placementOneLink: https://testdfa.alfabank.ru/mobile/goto/dfa_webview_with_two_parameters?dfaId=BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaId: BpYrHah7gVmAMHH36Sg3znwCzwYfW4vrXmEtwhJhsqLP + dfaName: ALFB-1-SB-082023-00001 + dfaType: MONEY_CLAIM + dfaQualificationPersonRequirements: ALL + dfaQualificationCompanyRequirements: ALL + dfaBankAccount: "47422810800000000000" + companyIssuerId: 8rJg73mcacMn5p6Fmpsre1Jk3rwU4yz7UzDpFfGyShH4 + companyIssuerName: АО Вольт + companyIssuerOgrn: "1130731080666" + companyIssuerAddress: Октябрьская улица 123 д. 18 + companyIssuerEmail: volt@mail.ru + companyIssuerSite: volt.ru + companyIssuerInn: "514564365" + dfaParValue: 100000 + dfaCurrency: RUB + dfaRestriction: true + dfaRestrictionValue: 44650800 + dfaRateType: FIXED + dfaRateAmount: "13.2" + dfaNpdPaymentPeriod: EOP + dfaNpdPaymentPeriodComment: комментарий + dfaNpdAccrualPeriod: EOP + dfaNpdAccrualPeriodComment: комментарий + dfaDebtAccrualPeriod: EOP + dfaDebtAccrualPeriodComment: комментарий + dfaDebtPaymentPeriod: EOP + dfaDebtPaymentPeriodComment: комментарий + dfaRedemptionDate: 2027-08-18 + status: PRESALE + statusDate: 2023-08-03T14:17:51.525Z + dfaMinValue: 1000000 + dfaMaxValue: 1000000 + dfaMinNumber: 1 + dfaMaxNumber: 7 + dfaRateRangeEnable: true + dfaMinRate: 5.7 + dfaMaxRate: 15.3 + dfaStartDate: 2023-02-01T00:00:00Z + dfaEndDate: 2023-02-01T00:00:00Z + dfaSaleEndDate: 2023-08-03T14:17:51.525Z + dfaDocIconName: sample.jpg + dfaDocIconKey: /dfa/icons/d82ffa63-bda0-4e56-92e7-522829a721ba + dfaDocConditionsName: Презентация.pdf + dfaDocConditionsKey: docs/15cc2bfd-48bc-484b-97f1-c8913cc5372d + dfaDocPresentationKey: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + dfaDocPresentationName: Презентация.pdf + dfaReleaseDecisionKey: docs/5f5537b4-d633-4c1b-8e9f-4d3406162246 + dfaReleaseDecisionName: Презентация.pdf + dfaInvestorFee: 1.1 + dfaSecondaryBuyerFee: 1.2 + dfaSecondarySellerFee: 1.3 + tokensaleHardcap: true + availableOnSecondaryMarket: true + dfaPriceStep: 100 + dfaBorrowerName: Иванов Иван Иванович + dfaBorrowerInn: "369930244602" + dfaBorrowerOgrn: "6131238182674" + dfaLoanNumber: "654321" + dfaLoanAmount: Отсутствует + dfaLoanRateType: FIXED + dfaLoanRate: 10.6 + dfaLoanStartDate: 2023-08-03T14:17:51.525Z + dfaLoanEndDate: 2023-08-03T14:17:51.525Z + dfaMinBuyPrice: 100000 + dfaMaxBuyPrice: 1000000 + dfaMinSellPrice: 50000 + dfaMaxSellPrice: 500000 + profitOnDfa: 0 + contractVersion: 53 + exchangeContractVersion: 54 + creationDate: 2023-08-03T14:17:51.525Z + dfaTotalAmount: 10000 + dfaIssuerFee: 3.0 + dfaHybridSelectedTypes: + - CASH + dfaHybridPaymentDeadline: В рублях в течение 3-х рабочих дней с момента + направления Эмитенту Заявки на погашение ЦФА + dfaHybridAssetDeadline: В течение 10 рабочих дней с момента направления + Эмитенту Заявки на погашение ЦФА + dfaHybridAssetAddress: г. Москва + dfaSecondaryQualificationPersonRequirements: QUALIFIED_ONLY + dfaSecondaryQualificationCompanyRequirements: QUALIFIED_ONLY + dfaHardcapEnd: 15 + dfaSecondaryStartDate: 2023-08-03T14:17:51.525Z + dfaAvailableForIssuer: true + redemptionRule: BY_AMORTIZATION + dfaProductVariety: Наименование типа продукта для покупателя + dfaSubType: Структурная облигация + dfaPrettyName: Лабиринт + dfaExtraInfoList: 1 ЦФА = 1 кв.м + dfaLifeTime: "10000" + refAsset: + name: Структурная облигация + blocks: + - name: external + isRequired: true + visibility: + - COMPANY + - PERSON + parameters: + - name: title + value: Альфа Банк + isRequired: true + visibility: + - COMPANY + - PERSON + - name: subtitle + value: Структурная облигация + isRequired: true + visibility: + - COMPANY + - PERSON + - name: salesPoints + isRequired: false + visibility: + - COMPANY + - PERSON + parameters: + - name: title_1 + value: Высокая доходность + isRequired: false + visibility: + - COMPANY + - PERSON + - name: description_1 + value: Высокая доходность при отсутствии резко-негативных колебаний + цен на базовые активы + isRequired: false + visibility: + - COMPANY + - PERSON + - name: icon_1 + value: profit1Icon + isRequired: false + visibility: + - COMPANY + - PERSON + dfaDocs: + - order: 1 + preferences: + id: 0ec417b6-6e4a-4a20-9abf-0fa861914cfe + name: Презентация + isRequired: false + visibility: + - COMPANY + - PERSON + formats: + - PDF + - PNG + description: Презентация выпуска + singleFile: false + noDuplicates: false + files: + - id: 3f39cde3-76c2-4bdb-b2da-ef3f8491fcc1 + name: Презентация.pdf + url: https://testdfa.alfabank.ru:9010/dfa/docs/62979838-de96-41dd-a47a-91c74c97ecf2 + key: docs/55ac2445-19fc-44d5-94c8-764a827764ba + responseGetCertificates: + summary: Пример ответа на получение всех сертификатов + value: + - id: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + clientId: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + ownerName: Кудрявцев Ермолай Игоревич + fingerprint: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + organizationName: ООО 'Ромашка' + beginDateTime: 2023-07-28T15:11:14Z + expireDateTime: 2025-06-19T11:48:06Z + status: ACTIVE + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: ENCRYPTION + algorithm: RS256 + serialNumber: "2163173489423972678179275487230070851350268586" + requestAddCertificate: + summary: Пример запроса на добавление сертификата + value: + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: ENCRYPTION + responseAddCertificate: + summary: Пример ответа на добваление сертификата + value: + id: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + clientId: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + ownerName: Кудрявцев Ермолай Игоревич + fingerprint: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + organizationName: ООО 'Ромашка' + beginDateTime: 2023-07-28T15:11:14Z + expireDateTime: 2025-06-19T11:48:06Z + status: ACTIVE + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: ENCRYPTION + algorithm: RS256 + serialNumber: "2163173489423972678179275487230070851350268586" + requestChangeCertificate: + summary: Пример запроса на обновление сертификата + value: + op: replace + path: /status + value: ACTIVE + responseChangeCertificate: + summary: Пример ответа на обновление сертификата + value: + id: 9610bc6b-f06b-41b6-bae9-6bb5b06a54dd + clientId: 4aa56f35-abb1-4ebe-9697-389cca4a4475 + ownerName: Кудрявцев Ермолай Игоревич + fingerprint: 333773d77ef05aa9f7b7bae8e2779418b2aedb6a + organizationName: ООО 'Ромашка' + beginDateTime: 2023-07-28T15:11:14Z + expireDateTime: 2025-06-19T11:48:06Z + status: ACTIVE + certificateBody: MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI= + type: ENCRYPTION + algorithm: RS256 + serialNumber: "2163173489423972678179275487230070851350268586" + claims-resolved: + summary: Пример запроса для передачи обработанных обращений + value: + resolutionDate: 2025-06-26T09:09:32+03 + resolution: POSITIVE + orderId: Ad-2b47 + clientReply: "Заказ был частично возвращен, поэтому начисление кэшбэка отм\ + енено" + employeeReply: По частично возвращаенным заказам кэшбэк не начисляется + CreateOrderTravelRequest: + summary: Пример запроса на создание заказа Travel + value: + order: + externalId: AVIA-78901 + accountType: Мили + ruleId: 12 + type: AVIA + dateTime: 2023-10-05T14:30:00.000Z + totalSum: 25410.5 + bonusPayment: + - type: 0 + sumRubEquivalent: 5000 + sum: 10000 + comment: Оплата милями + cashPayment: + - type: Оплата картой + sum: 20410.5 + currency: RUB + content: + reservationSource: WEBVIEW + tripType: OW + segments: + - class: A + type: REGULAR + number: SU-123 + supplier: Aeroflot + departure: + city: MOW + country: RUS + point: SVO + dateTime: 2023-11-20T08:00:00.000Z + arrival: + city: IST + country: TUR + point: IST + dateTime: 2023-11-20T11:30:00.000Z + travelers: + adults: 2 + children: 1 + infants: 0 + reportData: + bookingType: GDS + startPrice: 20000.0 + markup: 5410.5 + SuccessResponseCreateOrder: + summary: Пример ответа на создание заказа + value: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Created + SuccessResponseAlreadyOrder: + summary: Пример ответа заказ уже создан + value: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Order already exists + CreateOrderAfishaRequest: + summary: Пример запроса на создание заказа Afisha + value: + order: + externalId: AFISHA-789 + accountType: Бонусные рубли + type: EVENT + dateTime: 2023-12-15T19:00:00.000Z + totalSum: 2500.5 + content: + eventName: Концерт группы 'Кино' + eventId: KINO-2023 + venue: Крокус Сити Холл + country: RUS + city: MOW + date: 2023-12-20T20:00:00.000Z + address: "г. Москва, 66-й км МКАД" + tickets: + - sector: A + row: "5" + seat: "12" + - sector: A + row: "5" + seat: "13" + UpdateOrderTravelRequest: + summary: Пример запроса на обновление заказа Travel + value: + order: + externalId: TRAVEL-456 + type: AVIA + dateTime: 2023-11-10T15:30:00.000Z + totalSum: 35000.75 + changeReason: CHANGE_TIMETABLE + content: + reservationSource: SITE + segments: + - departure: + city: MOW + country: RUS + point: SVO + dateTime: 2023-12-01T10:00:00.000Z + arrival: + city: IST + country: TUR + point: IST + dateTime: 2023-12-01T14:30:00.000Z + ConfirmationRequest: + summary: Пример запроса на подтверждение заказа + value: + comment: Подтверждаю оплату милями + paymentTransaction: + - sum: 15000 + currency: RUB + maskedCardNumber: 123456******7890 + rrn: "1498745362575217925125545565" + dateTime: 2023-10-05T14:30:00.000Z + SuccessResponseConfirmationOrder: + summary: Пример ответа на подтверждение заказа + value: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Confirmed + SuccessConfirmAlreadyOrder: + summary: Пример ответа подтвержденного заказа + value: + orderId: 40b3c2d2-e491-4b19-94cd-461e6fa35a60 + status: Order already confirmed + PatchDeactivateRequest: + summary: Пример запроса на деактивацию заказа + value: + accountType: Мили + sumRubEquivalent: 10000 + sum: 5000 + comment: Добровольный возврат + SuccessResponseBonus: + summary: Пример ответа на создание заказа + value: + - typeName: AlfaTravel + balance: 189594 + unitName: Мили + createRegistryRequest: + summary: Пример запроса + value: + registryId: "039012000001000" + expirationDate: 2025-08-05T11:00:00+03:00 + admPid: "00330456" + clientStoreCode: ShopCode001 + paymentAgentInf: + accountNumber: "40821810801850000018" + selfEncashmentAmount: "100.00" + bankPaymentAgentInf: + accountNumber: "40821810501850000004" + selfEncashmentAmount: "100.00" + clientInf: + accountNumber: "40702810701850008187" + selfEncashmentAmount: "100.00" + email: client@example.com + cancelRegistriesRequest: + summary: Пример запроса + value: + registryIds: + - "039012000001000" + - "039012000001001" + getAdmResponse: + summary: Пример ответа + value: + pagination: + limit: 10 + offset: 0 + totalCount: 2 + items: + - admPid: "00330456" + status: 1 + statusDescription: Устройство полностью работоспособно + admSoftwareVersion: 2.1.8 + billValidatorSoftwareVersion: 1.0.4 + - admPid: "00349012" + status: 1 + statusDescription: Устройство полностью работоспособно + admSoftwareVersion: 2.1.8 + billValidatorSoftwareVersion: 1.0.4 + create_individual_example: + value: + city: + cityId: 1 + regionId: 77 + presenceCityTitle: Москва + agreement: true + contactInfo: + lastName: Петров + firstName: Иван + middleName: Сергеевич + phone: "79005553322" + email: ivan.petrov@example.ru + create_llc_example: + value: + city: + cityId: 2 + regionId: 78 + presenceCityTitle: Санкт-Петербург + agreement: true + contactInfo: + lastName: Петров + firstName: Пётр + middleName: Петрович + phone: "79001234567" + email: p.petrov@example.ru + clientName: + - language: RU + full: Общество с ограниченной ответственностью «Альфа Технологии» + short: ООО «Альфа Технологии» + - language: EN + full: Alpha Technologies LLC + short: AlphaTech + getComplianceScoreResponse: + summary: Пример ответа + value: + inn: "1234567890" + rawScore: 0 + riskLevel: medium + boundaries: + low: 0.6 + high: 0.9 + headers: + x-fapi-interaction-id: + description: "RFC4122 UID, используемый в качестве идентификатора корреляции\ + . Если необходимо, то Сторонний поставщик передает обратно значение иденти\ + фикатора корреляции в заголовке ответа x-fapi-interaction-id." + required: true + schema: + type: string + description: "Универсальный уникальный идентификатор (UUID) версии 4, в со\ + ответствии с IETC RFC 4122 \"Universally Unique IDentifier (UUID) URN Namespace\"\ + ." + format: uuid + example: 97ed4827-7b6f-4491-a06f-b548d5a7512d + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT diff --git a/_docs/xml/alfa_payin_docs.xml b/_docs/xml/alfa_payin_docs.xml new file mode 100644 index 0000000..6af65e1 --- /dev/null +++ b/_docs/xml/alfa_payin_docs.xml @@ -0,0 +1,12149 @@ + + + + + + + + **Примечание** +> Наличие приложения Альфа-Бизнес Мобайл (АБМ) является условием входа по QR-коду. + +--- + +### Электронная подпись + +Аутентификация с помощью электронной подписи (ЭП) — это технология, основанная на применении средств криптографической защиты информации, для использования которой необходимо наличие токена (USB-носитель) с сертификатом и специализированного программного обеспечения на компьютере. + +Для аутентификации используются следующие виды ЭП: + +- квалифицированная электронная подпись (КЭП); +- сертификат Альфа-Банка (неквалифицированная электронная подпись, НЭП). + +#### Квалифицированная электронная подпись (КЭП) + +**Процесс аутентификации:** + +1. Вставить токен с сертификатом КЭП в компьютер. +2. Нажать на кнопку «Войти по токену». +3. Нажать на кнопку «С сертификатом КЭП». +4. Выбрать необходимый сертификат из списка. +5. Ввести пароль (при его наличии) от сертификата. +6. Ввести пароль от учётной записи Банка. + +#### Сертификат Альфа-Банка (НЭП) + +**Процесс аутентификации:** + +1. Вставить токен с сертификатом Альфа-Банка (НЭП) в компьютер. +2. Нажать на кнопку «Войти по токену». +3. Нажать на кнопку «С сертификатом Альфа-Банка». +4. Выбрать необходимый сертификат из списка. +5. Ввести пароль от токена. +6. Ввести пароль от учётной записи Банка. + +--- + +### Биометрия + +Аутентификация с помощью биометрических данных является одним из наиболее надёжных методов защиты информации. Она позволяет идентифицировать пользователя на основе его уникальных физических характеристик (отпечаток пальца, лицо). + +**Процесс аутентификации:** + +1. Выберите «Быстрый вход». +2. Приложите палец или отсканируйте лицо. + +> **Примечание** +> +> 1. Данный способ аутентификации работает на устройствах, поддерживающих работу с биометрическими данными. +> 2. Для того чтобы использовать данный способ аутентификации, необходимо предварительно пройти регистрацию биометрических данных при входе через логин и пароль. + +--- + +### Навигация + +- [← Что такое Alfa ID](/products/alfa-api/documentation/articles/alfa-id/articles/intro/intro) +- [Кнопка входа по Alfa ID →](/products/alfa-api/documentation/articles/alfa-id/articles/button/button) + +]]> + + + + **Внимание** +> Токен обновления действует 180 дней и не может быть использован более 2 раз. + +> **Внимание** +> Токен обновления может быть отозван в случае, если: +> +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +В результате запроса, помимо нового токена доступа, вы также получите новый токен обновления, а старый `refresh_token` станет недействительным. + +При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. В то время как `redirect_uri` экранировать не нужно. + +Если запрос отправляется через Postman с заголовком `"Content-Type": "application/x-www-form-urlencoded"` и `body` в формате `x-www-form-urlencoded` — нет необходимости экранировать специальные символы. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `refresh_token` | +| **refresh_token** | string | required | Токен обновления. Обновить `access_token` через `refresh_token` можно только 2 раза. В дальнейшем необходимо использовать новый `refresh_token` | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**HEADERS** + +- **Content-Type**: `application/json` +- **Cache-Control**: `no-store` +- **Pragma**: `no-cache` + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена (например, `Bearer`) | +| **expires_in** | integer | optional | Срок жизни токена в секундах | + +**Пример JSON-ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +--- + +### Ошибка (400 Bad Request) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Возможные значения: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Навигация + +- [← Получение профиля представителя пользователя](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/get-profile-info/v1/get-profile-info) +- [Как использовать ACF для H2H →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) + +]]> + + + + + + **Внимание** +> +> - Токен доступа действует **1 час**. +> - Токен доступа может быть отозван в случае, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован; +> - срок жизни согласия пользователя истёк. + +### Особенности передачи параметров + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо **экранировать** специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** (body в формате `x-www-form-urlencoded`) — экранировать специальные символы не требуется. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :--------------- | :----- | :---- | :---------------------------------- | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/x-www-form-urlencoded` | + +### BODY (x-www-form-urlencoded) + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :--------------------------------------------------- | +| **grant_type** | string | Да | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | Да | Код авторизации | +| **client_id** | string | Да | Идентификатор партнёрского сервиса | +| **client_secret** | string | Да | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | Да | URI перенаправления | +| **code_verifier** | string | Нет | Код верификатор | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +## Параметры ответа + +### Ответ 200 (OK) + +**HEADERS** + +- `Content-Type`: `application/json` +- `Cache-Control`: `no-store` +- `Pragma`: `no-cache` + +**BODY** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | Да | Токен доступа | +| **refresh_token** | string | Да | Токен обновления | +| **token_type** | string | Да | Тип токена (обычно `Bearer`) | +| **expires_in** | integer | Нет | Срок жизни токена в секундах | +| **id_token** | string | Да | Идентификационный токен | + +**Пример JSON-ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +--- + +### Ответ 400 (Bad Request) + +| Атрибут | Тип | Обяз. | Описание | +| :-------------------- | :----- | :---- | :--------------------------------------- | +| **error** | string | Да | Код ошибки (например, `invalid_request`) | +| **error_description** | string | Нет | Описание ошибки | + +--- + +## Таблица возможных значений параметра error + +| Значение | Описание | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------ | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неподдерживаемый метод). | +| `invalid_grant` | Недействительный код авторизации, токен обновления или несоответствие URI перенаправления. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка. | + +--- + +## Описание клэймов (claims) + +### access_token + +| Значение | Описание | +| :----------------- | :----------------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix timestamp) | +| **iat** | Время выпуска токена (Unix timestamp) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +### id_token + +| Значение | Описание | Scope | +| :------------ | :--------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Строка для защиты от повторных атак | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | + +]]> + + + **Важно:** При формировании ссылки указывайте весь доступный `scope` через знак пробела или `%20`. Параметр `prompt=consent` используйте только если нужно, чтобы пользователь повторно подписал согласие. + +#### Параметры запроса (QUERY) + +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| `response_type` | string | Да | Тип ответа. Возможные значения: `code` | +| `client_id` | string | Да | Идентификатор партнёрского сервиса (выдается банком) | +| `redirect_uri` | string | Да | URI для перенаправления пользователя после успешной авторизации | +| `scope` | string | Да | Область применения (информирует, какие данные будут использованы) | +| `state` | string | Да | Параметр для защиты от CSRF. UUID, 36 символов. | +| `nonce` | string | Нет | Строка для связи сессии с ID-токеном и защиты от повторных атак | +| `code_challenge` | string | Нет | Код вызова | +| `code_challenge_method` | string | Нет | Метод преобразования: `plain` или `S256` | +| `prompt` | string | Нет | Параметр повторной аутентификации: `none`, `login`, `consent` | +| `max_age` | string | Нет | Максимальный период аутентификации | + +#### Пример запроса +```bash +curl -X GET https://id.alfabank.ru/oidc/authorize?response_type=code&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode&scope=openid&state=abcdef +``` + +--- + +### Шаг 3. Аутентификация пользователя + +1. Пользователь проходит процедуру аутентификации. +![loginPassword](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/picture4.png) + +2. Пользователь выбирает организацию (для ЮЛ; для ФЛ шаг пропускается). +![organisationUL](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/picture6.png) + +3. Пользователь подписывает форму согласия. +![signForm](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf/articles/get-auth-code/v1/files/signForm.png) + +--- + +### Шаг 4. Получение кода авторизации + +Код авторизации получен, если пришел ответ **302 Found**. + +> **Внимание:** Код авторизации действует **2 минуты** и может быть использован только **1 раз**. + +#### Пример успешного ответа +```bash +https://wwww.partner.ru/code?code=8962c304-89b1-11ec-a8a3-0242ac120002&state=abcdef +-H 'Location: https://wwww.partner.ru/code?code=8962c304-89b1-11ec-a8a3-0242ac120002&state=abcdef' +-H 'Set-Cookie: ALFASESSIONID=f9e9532f-7b06-4023-83a2-f6cc77a7bfe4' +``` + +#### Параметры ответа (302 Found) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| `Location` | string | Содержит URI перенаправления вида: `redirect_uri?code={code}&state={state}` | +| `Set-Cookie` | string | Содержит идентификатор сессии | + +--- + +### Ошибки + +В случае неуспешного выполнения запроса в заголовке `Location` передаётся строка вида: `redirect_uri_error_page?error={error}`. + +#### Таблица возможных значений параметра error + +| Значение | Описание | +| :--- | :--- | +| `unsupported_response_type` | Сервер не поддерживает получение кода этим методом | +| `login_required` | Необходима аутентификация (возникает при `prompt=none`) | +| `invalid_scope` | Недопустимая или неизвестная область применения | +| `invalid_request` | Отсутствует обязательный параметр или неверный формат запроса | +| `consent_required` | Необходимо согласие пользователя (возникает при `prompt=none`) | +| `access_denied` | Владелец ресурса или сервер отклонил запрос | +| `invalid_operation_response` | Используйте только данные из спецификации ACF | +| `login_expired` | Пользователь не прошел аутентификацию за 15 минут или сделал logout | + +--- +**Далее:** [Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/get-access-token/v1/get-access-token) + +]]> + + + Для каждого Партнёра API перечень допустимых клэймов настраивается индивидуально. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :-------------------- | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/jwt | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/userinfo' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/jwt' +``` + +--- + +## Параметры ответа + +### 200 OK + +**Headers:** + +- `Content-Type: application/jwt` (optional) + +**Пример ответа (JWT):** + +```text +eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJjdXMiOiJVQUFBQUEiLCJzdWIiOiIzMjI4ZTY4ZS1jYzM0LTRiODItYjQzZC00OTExMmI1ZDlkM2UiLCJiaXJ0aGRhdGUiOiIyMDAwLTAyLTIwIiwicm9sZSI6IkFDQ09VTlRBTlQsIE1BTkFHRVIiLCJnZW5kZXIiOiJNQUxFIiwiaWRlbnRpdHlfZG9jdW1lbnRfbmFtZSI6ItCf0LDRgdC_0L7RgNGCINCz0YDQsNC20LTQsNC90LjQvdCwINCg0KQiLCJpZGVudGl0eV9kb2N1bWVudF9udW1iZXIiOjIyMjIyMiwiaXNzIjoiaHR0cHM6XC9cL2JhYXMuYWxmYWJhbmsucnUiLCJpbm4iOjc0MTUxMTExMjIyMiwiZWlvIjp0cnVlLCJnaXZlbl9uYW1lIjoi0KLQtdGB0YIiLCJtaWRkbGVfbmFtZSI6ItCi0LXRgdGC0L7QstC40YciLCJhY3VzIjoiWEFBQUFBIiwiaWRlbnRpdHlfZG9jdW1lbnRfc2VyaWVzIjoxMTExLCJhdWQiOiIwY2VlMDY4My04NWFlLTQ5ZjItYTYzZC0yOWY5N2FhZDE5MTEiLCJhY2xjIjoiWEFBQUExIiwidXBkYXRlZF9hdCI6IjIwMjItMDEtMjAiLCJuYW1lIjoi0KLQtdGB0YLQvtCyINCi0LXRgdGCINCi0LXRgdGC0L7QstC40YciLCJwaG9uZV9udW1iZXIiOjc5MTkxMTEyMjMzLCJjbGMiOiJVQUFBQTEiLCJmYW1pbHlfbmFtZSI6ItCi0LXRgdGC0L7QsiIsImVtYWlsIjoiZW1haWxAZW1haWwucnUifQ.WVr5xkQSEGqpPXN3aIo0zHZLDL0vvtxEEQ83BrgJo7l0BjjALeGDRYENF2bL8j3n1pXRnduiBQcYNV6teBhESI8V_8kd7Kh7LTePkJWadPSvD__KskC69b4XZ-zN-IQ73NmAcBDStnnhSXGKL6xhdRy-TGiAoKPsRWiDVntsDlpCQNHAt3tJk8q_SQS4S1k6qju9eJ2GFkgmd6z8rR2vaBykaOF0K61ltksw6YgXhuek3OlYkqIAivyKYl59uio8zMpJk-YrPlmawwmvWPF0vKhaLj8Mvn4mVMsVSfuVVKP2ksHG0MAlWpO3Sh9GoKO4d6TQplJ4vgIIeNx-44npqw +``` + +### 400 Bad Request + +**Body:** + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Принимает значения: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Описание клэймов UserInfo + +| Name | Description | Scope | +| :-------------- | :-------------------------------------------------------------------- | :------------------ | +| **iss** | URL-адрес Alfa ID по протоколу https (https://id.alfabank.ru/oidc) | openid | +| **sub** | Уникальный идентификатор Alfa ID пользователя (до 255 символов ASCII) | openid | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | openid | +| **name** | Полное имя конечного пользователя в отображаемой форме | profile, name | +| **given_name** | Имя конечного пользователя | profile, givenname | +| **family_name** | Фамилия конечного пользователя | profile, familyname | +| **middle_name** | Отчество конечного пользователя | profile, middlename | +| **email** | Предпочтительный адрес электронной почты | email | +| **gender** | Пол конечного пользователя | profile, gender | +| **birthdate** | День рождения в формате `YYYY-MM-DD` | profile, birthdate | + +]]> + + + + + **Внимание** +> Токен доступа действует **1 час**. + +> **Внимание** +> Токен доступа может быть отозван в случае, если: +> +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. В то время как `redirect_uri` экранировать не нужно. + +Если запрос отправляется через Postman с заголовком `"Content-Type": "application/x-www-form-urlencoded"` и `body` в формате `x-www-form-urlencoded` — нет необходимости экранировать специальные символы. + +Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | required | Код авторизации | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | required | URI перенаправления | +| **code_verifier** | string | optional | Код верификатор | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +### Параметры ответа + +#### Пример ответа 200 (OK) + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +#### Описание полей BODY (200 OK) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------ | :------------- | :--------------------------- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена | +| **expires_in** | integer | optional | Срок жизни токена в секундах | +| **id_token** | string | required | Идентификационный токен | + +--- + +### Ошибки (400 Bad Request) + +| Значение | Описание | +| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **invalid_request** | Отсутствует обязательный параметр, неподдерживаемое значение параметра (кроме grant_type), повторение параметра, несколько учётных данных или неправильный формат запроса | +| **invalid_client** | Ошибка аутентификации клиента (неизвестный клиент, отключенная аутентификация клиента или неподдерживаемый метод аутентификации) | +| **invalid_grant** | Недействительное разрешение авторизации (недействительный код авторизации, токен обновления или несоответствие URI перенаправления) | +| **unsupported_grant_type** | Тип разрешения на авторизацию (grant_type) не поддерживается сервером авторизации | +| **internal_error** | Произошла непредвиденная ошибка | + +--- + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :-------------------------------------------------------------------- | +| **iss** | URL-адрес Alfa ID по протоколу https (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя (до 255 символов ASCII) | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix timestamp UTC) | +| **iat** | Время выпуска токена (Unix timestamp UTC) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +### Описание клэймов ID_TOKEN + +| Значение | Описание | Scope | +| :------------ | :--------------------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Значение для связи сессии и защиты от повторных атак | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | + +--- + +**Навигация:** + +- [← Получение кода авторизации](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/get-auth-code) +- [Обновление токена доступа →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/token-update/v1/token-update) + +]]> + + + + + + **Внимание** +> Не забывайте заменить `{client_id}` на реальное значение, полученное после регистрации приложения на стороне Банка. + +--- + +### Шаг 2. Аутентификация + +1. В окне браузера отобразится страница аутентификации Alfa ID для ввода логина/пароля пользователя: + +![authAlfaID](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture8.png) + +2. После ввода логина/пароля пользователя отобразится страница второго фактора аутентификации для ввода otp-кода (sms, push): + +![otpCode](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture9.png) + +3. Необходимо ввести полученный на телефон otp-код (sms, push), и в адресной строке браузера отобразится код авторизации (`code`): + +![authorizationCode](/assets/developers-portal.docs.alfa-api/articles/alfa-id/articles/acf-h2h/articles/get-auth-code/v1/files/picture11.jpg) + +--- + +### Шаг 3. Получение кода авторизации + +Полученное в браузере **значение кода авторизации** (параметр `code` в URL) необходимо скопировать и **обменять на [токен доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-access-token/v1/get-access-token)**. + +> **Внимание** +> Код авторизации по умолчанию действует **2 минуты** и может быть использован только **1 раз**. + +--- + +**Навигация:** + +- [← Как использовать ACF для H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) +- [Получение токена доступа →](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/get-access-token/v1/get-access-token) + +]]> + + + [!IMPORTANT] +> **Внимание** +> +> - Токен обновления действует **180 дней** и не может быть использован более **2 раз**. +> - Токен обновления может быть отозван, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован. + +### Особенности кодирования + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** с телом в формате `x-www-form-urlencoded` — экранировать символы вручную не требуется. +- Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `refresh_token` | +| **refresh_token** | string | required | Токен обновления. Обновить `access_token` можно только 2 раза. В дальнейшем нужно использовать новый `refresh_token`. | +| **client_id** | string | required | Идентификатор партнёрского сервиса. | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса. | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **access_token** | string | required | Новый токен доступа. | +| **refresh_token** | string | required | Новый токен обновления. | +| **token_type** | string | required | Тип токена (обычно `Bearer`). | +| **expires_in** | integer | optional | Срок жизни токена в секундах. | + +**Пример ответа:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +### Ошибка (400 Bad Request) + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Например: `invalid_request` (неверные входные параметры). | +| **error_description** | string | optional | Текстовое описание ошибки. | + +--- + +## Дополнительная информация + +### Таблица возможных значений параметра error + +| Значение | Описание | +| :----------------------- | :---------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный ID или неверный secret). | +| `invalid_grant` | Недействительный токен обновления или несоответствие URI. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Внутренняя ошибка сервера. | + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :----------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc). | +| **sub** | Уникальный идентификатор пользователя. | +| **aud** | Идентификатор сервиса-партнёра (аудитория). | +| **exp** | Время окончания срока действия (Unix timestamp). | +| **iat** | Время выпуска токена. | +| **scope_claims** | Массив клэймов области применения. | +| **scope_services** | Массив операций области применения. | + +]]> + + + + + **Внимание** +> +> - Токен обновления действует **180 дней** и не может быть использован **более 2 раз**. +> - При использовании `curl` запроса с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо экранировать специальные символы параметра `client_secret`. При этом `redirect_uri` экранировать не нужно. +> - Если запрос отправляется через **Postman** с телом в формате `x-www-form-urlencoded` — экранировать символы не нужно. +> - Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +### Токен обновления может быть отозван, если: + +- пользователь сменил пароль; +- пользователь превысил допустимое количество попыток ввода пароля; +- аккаунт пользователя был заблокирован. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :--------------- | :----- | :---- | :---------------------------------- | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/x-www-form-urlencoded` | + +### BODY (x-www-form-urlencoded) + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :-------------------------------------------------- | +| **grant_type** | string | Да | Тип гранта. Значение: `refresh_token` | +| **refresh_token** | string | Да | Токен обновления. Можно использовать только 2 раза. | +| **client_id** | string | Да | Идентификатор партнёрского сервиса | +| **client_secret** | string | Да | Секретный ключ партнёрского сервиса | + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=refresh_token' \ +--data-urlencode 'refresh_token=13b8230b-b6bf-4bb9-b977-3bc0a988a5fd' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :---------------- | :------ | :----------------------------------- | +| **access_token** | string | Новый токен доступа | +| **refresh_token** | string | Новый токен обновления | +| **token_type** | string | Тип токена (обычно `Bearer`) | +| **expires_in** | integer | Срок жизни токена доступа в секундах | + +**Пример ответа 200:** + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0...", + "refresh_token": "2cc8d34c-130a-4674-91fa-f9835fff6e88", + "token_type": "Bearer", + "expires_in": 3600 +} +``` + +### Ошибка (400 Bad Request) + +| Атрибут | Тип | Описание | +| :-------------------- | :----- | :--------------------------------------- | +| **error** | string | Код ошибки (например, `invalid_request`) | +| **error_description** | string | Описание ошибки | + +--- + +## Справочные таблицы + +### Возможные значения параметра error + +| Значение | Описание | +| :----------------------- | :-------------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неверный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неверный `client_secret`). | +| `invalid_grant` | Недействительный `refresh_token`. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка на стороне сервера. | + +### Описание клэймов access_token + +| Клэйм | Описание | +| :----------------- | :----------------------------------------------------- | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор Alfa ID пользователя | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия токена (Unix Timestamp) | +| **iat** | Время выпуска токена (Unix Timestamp) | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +**Полезные ссылки:** + +- [Новости в Telegram](https://t.me/AlfaAPI) +- [Общая спецификация Alfa API](/products/alfa-api/documentation/articles/specification/specification) +- [Инструкция по подключению](/products/alfa-api/documentation/articles/connection/connection) + +]]> + + + **Внимание** +> Код авторизации по умолчанию действует **2 минуты** и может быть использован только **1 раз**. + +--- + +**Далее:** [Получение токена доступа](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/get-access-token/v1/get-access-token) +**Назад:** [Как использовать ACF для холдингов](/products/alfa-api/documentation/articles/alfa-id/articles/acf-holding/articles/intro/intro) + +]]> + + + + + + **⚠️ Внимание** +> +> - Токен доступа действует **1 час**. +> - Токен доступа может быть отозван, если: +> - пользователь сменил пароль; +> - пользователь превысил допустимое количество попыток ввода пароля; +> - аккаунт пользователя был заблокирован; +> - срок жизни согласия пользователя истёк. + +#### Особенности кодирования: + +- При использовании `curl` с заголовком `"Content-Type": "application/x-www-form-urlencoded"` необходимо **экранировать** специальные символы параметра `client_secret`. Параметр `redirect_uri` экранировать не нужно. +- Если запрос отправляется через **Postman** (формат `x-www-form-urlencoded`) — экранировать символы вручную не требуется. +- Подробную информацию по экранированию можно посмотреть [здесь](/products/alfa-api/documentation/articles/alfa-id/articles/screening/screening). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------------- | :----- | :------------- | :---------------------------------- | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/x-www-form-urlencoded` | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :--------------------------------------------------- | +| **grant_type** | string | required | Тип гранта. Возможные значения: `authorization_code` | +| **code** | string | required | Код авторизации | +| **client_id** | string | required | Идентификатор партнёрского сервиса | +| **client_secret** | string | required | Секретный ключ партнёрского сервиса | +| **redirect_uri** | string | required | URI перенаправления | +| **code_verifier** | string | optional | Код верификатор | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' \ +--data-urlencode 'code_verifier=string' +``` + +--- + +### Параметры ответа + +#### Пример ответа 200 (OK) + +```json +{ + "access_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ...", + "refresh_token": "13b8230b-b6bf-4bb9-b977-3bc0a988a5fd", + "token_type": "Bearer", + "expires_in": 3600, + "id_token": "eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ..." +} +``` + +#### Описание полей ответа (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------ | :------------- | :--------------------------- | +| **access_token** | string | required | Токен доступа | +| **refresh_token** | string | required | Токен обновления | +| **token_type** | string | required | Тип токена (Bearer) | +| **expires_in** | integer | optional | Срок жизни токена в секундах | +| **id_token** | string | required | Идентификационный токен | + +--- + +### Таблица возможных значений параметра error (400 Bad Request) + +| Значение | Описание | +| :----------------------- | :---------------------------------------------------------------------------------------------------------- | +| `invalid_request` | Отсутствует обязательный параметр, неподдерживаемое значение, повторение параметра или неправильный формат. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный клиент или неверный метод). | +| `invalid_grant` | Недействительный код авторизации, токен обновления или несоответствие URI. | +| `unsupported_grant_type` | Тип `grant_type` не поддерживается сервером. | +| `internal_error` | Произошла непредвиденная ошибка. | + +--- + +### Описание клэймов access_token + +| Значение | Описание | +| :----------------- | :------------------------------------------------ | +| **iss** | URL-адрес Alfa ID (https://id.alfabank.ru/oidc) | +| **sub** | Уникальный идентификатор пользователя Alfa ID | +| **aud** | Идентификатор сервиса-партнёра (аудитория токена) | +| **exp** | Время окончания срока действия (Unix timestamp) | +| **iat** | Время выпуска токена | +| **scope_claims** | Массив клэймов области применения | +| **scope_services** | Массив операций области применения | + +--- + +### Описание клэймов ID_TOKEN + +| Значение | Описание | Scope | +| :------------ | :-------------------------------------------------- | :----- | +| **iss** | URL-адрес Alfa ID | openid | +| **sub** | Уникальный идентификатор пользователя | openid | +| **aud** | Идентификатор сервиса-партнёра | openid | +| **exp** | Время окончания срока действия | openid | +| **iat** | Время выпуска JWT | openid | +| **auth_time** | Время аутентификации пользователя | openid | +| **nonce** | Значение для связи сессии (если передавалось ранее) | openid | +| **acr** | Способ аутентификации пользователя | openid | +| **azp** | Сторона, которой выдан токен (client_id) | openid | + +--- + +_Документация Alfa API_ + +]]> + + + + + **Важно:** Client Credentials Flow не позволяет использовать методы, которые содержат персональные данные пользователя или банковскую тайну. В соответствии с регуляторными требованиями, Банк обязан проверить полномочия представителя на получение такой информации. + +--- + +## Шаги авторизации + +1. **Получение токена доступа** (см. детали ниже). + +### Дополнительно + +При необходимости вы можете [отозвать токен](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/revoke-token/v1/revoke-token). + +--- + +## Техническая спецификация API + +### Получение токена доступа + +**Endpoint:** `POST https://baas.alfabank.ru/oidc/token` + +#### Заголовки (Headers) + +| Название | Обязательно | Значение | +| :------------- | :---------- | :---------------------------------- | +| `Content-Type` | Да | `application/x-www-form-urlencoded` | +| `Accept` | Да | `application/json` | + +#### Параметры тела запроса (Request Body) + +| Параметр | Тип | Описание | +| :-------------- | :----- | :---------------------------------------------------------------------------------------------------------- | +| `grant_type` | string | Тип гранта. Для CCF обычно используется `client_credentials` (в данном примере указан `authorization_code`) | +| `client_id` | uuid | Идентификатор партнёрского сервиса | +| `client_secret` | string | Секретный ключ партнёрского сервиса | +| `code` | uuid | Код авторизации | +| `redirect_uri` | string | URI перенаправления | + +--- + +## Примеры кода + +### cURL + +```bash +curl --location 'https://baas.alfabank.ru/oidc/token' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--header 'Accept: application/json' \ +--data-urlencode 'grant_type=authorization_code' \ +--data-urlencode 'code=8962c304-89b1-11ec-a8a3-0242ac120002' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'redirect_uri=https://wwww.partner.ru/code' +``` + +### Python + +```python +import requests + +url = "https://baas.alfabank.ru/oidc/token" +payload = 'grant_type=authorization_code&code=8962c304-89b1-11ec-a8a3-0242ac120002&client_id=0cee0683-85ae-49f2-a63d-29f97aad1911&client_secret=Qwerty1234567890Qwerty1234567890!&redirect_uri=https%3A%2F%2Fwwww.partner.ru%2Fcode' +headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json' +} + +response = requests.request("POST", url, headers=headers, data=payload) +print(response.text) +``` + +--- + +## Возможные ошибки (параметр `error`) + +| Значение | Описание | +| :----------------------- | :------------------------------------------------------------------ | +| `invalid_request` | Отсутствует обязательный параметр или неверный формат запроса. | +| `invalid_client` | Ошибка аутентификации клиента (неизвестный ID или неверный secret). | +| `invalid_grant` | Недействительный код авторизации или несоответствие redirect_uri. | +| `unsupported_grant_type` | Тип grant_type не поддерживается сервером. | +| `internal_error` | Внутренняя ошибка сервера. | + +--- + +## Структура ответа (Success 200 OK) + +При успешном запросе возвращается JSON со следующими полями: + +- `access_token`: Токен доступа (JWT). Действует 1 час. +- `refresh_token`: Токен для обновления access_token. +- `id_token`: Идентификационный токен. +- `expires_in`: Срок жизни токена в секундах (3600). +- `token_type`: Тип токена (Bearer). + +--- + +_Документация Alfa API. [Портал разработчика](https://developers.alfabank.ru)_ + +]]> + + + + + + + + + + +• `access_token` — токен доступа;
• `refresh_token` — токен обновления | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/oidc/revoke' \ +--header 'Content-Type: application/x-www-form-urlencoded' \ +--data-urlencode 'client_id=0cee0683-85ae-49f2-a63d-29f97aad1911' \ +--data-urlencode 'client_secret=Qwerty1234567890Qwerty1234567890!' \ +--data-urlencode 'token=string' \ +--data-urlencode 'token_type_hint=refresh_token' +``` + +--- + +## Параметры ответа + +### 200 OK + +Нет тела ответа. + +### 400 Bad Request + +**Headers:** + +- `Content-Type: application/json` (optional) + +**Body:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки. Возможные значения:
• `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +--- + +## Навигация + +- [← Проверка подписи](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/signature-checking/signature-checking) +- [Данные по согласиям пользователей →](/products/alfa-api/documentation/articles/alfa-id/articles/expansion/articles/client-consents/v1/client-consents) + +--- + +_Документация Alfa ID / Расширение сценариев_ + +]]> +
+ + + +
+ + + + + **Внимание для ИП:** +> Права разработчика можно назначить от имени самого ИП (роль «Руководитель») или от имени любого другого сотрудника с ролью «Руководитель» (потребуется подтверждение от владельца ИП). + +### Шаг 1. Перейдите в раздел «Пользователи и роли» + +На главном экране Альфа-Бизнес перейдите в настройки компании. +![image](files/1.png) +![image](files/2.png) +В разделе **Моя компания** выберите карточку **Пользователи и роли**. +![image](files/3.png) + +### Шаг 2. Создайте новую роль + +Нажмите **Создать роль**. +![image](files/4.png) +Укажите название роли (например, «Разработчик API»). +![image](files/5.png) + +Далее настройте права. Рекомендуется создавать роль на основании прав руководителя, сбросив лишнее: + +1. Нажмите **Снять все**, чтобы сбросить права руководителя. + ![image](files/6.png) +2. В разделе **Обслуживание бизнеса** выберите **Alfa API**, указав необходимые права. + ![image](files/7.png) +3. Нажмите **Создать роль** для сохранения. + +### Шаг 3. Назначьте роль разработчику + +В разделе **Пользователи** нажмите на три точки справа от нужного сотрудника и выберите **Сменить роль**. +![image](files/9.png) + +Выберите созданную роль и нажмите **Сменить**. +![image](files/11.png) + +Подтвердите смену роли кодом из СМС. +![image](files/12.png) + +После успешной смены в записи пользователя отобразится статус **Подключён**. Теперь пользователь может работать с Порталом разработчика. +![image](files/13.png) + +--- + +## Требования к полномочиям для авторизации + +Для корректной работы H2H-интеграций ключ доступа (`access_token` / `API Key`) должен получать пользователь, обладающий правами на конкретные сервисы: + +- **При использовании ACF H2H:** Авторизацию в Alfa ID должен проходить пользователь, у которого в Альфа-Бизнес настроены полномочия на использование выбранных `scopes`. +- **При использовании API Key:** Выпускать ключ должен пользователь, имеющий права на те продукты, которые выбраны при выпуске ключа. + +**Пример:** Если у разработчика есть права на редактирование интеграций, но нет прав на «Просмотр выписки», то выпущенный им API Key для сервиса `transactions` работать не будет. + +]]> + +
+ + + + + + + +<Вебхуки> + +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | +| **data** | `object` | optional | Дополнительные данные по вебхукам. Список полей зависит от события. Для `jp_sbp_incoming_payments` не заполняется. | +| **data.accounts** | `array of string` | optional | Список счетов. Заполняется при `object: ul_transaction_default`. Если не переданы, вебхук создается на все доступные счета. | +| **callbackUri** | `string` | **required** | URL партнёра. Должен соответствовать хосту `redirect_uri` из настроек Alfa ID (проверка по домену второго уровня). | +| **version** | `integer` | optional | Версия формата данных. Для текущих объектов возможное значение — `1`. | + +--- + +## Пример запроса + +```bash +curl -X POST https://baas.alfabank.ru/api/v1/webhooks \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "object": "ul_transaction_default", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ (201 Created) + +| Атрибут | Тип | Описание | +| :-------------- | :-------- | :------------------------------------------------------------------------ | +| **id** | `uuid` | Идентификатор записи вебхука. | +| **object** | `string` | Сущность подписки (`ul_transaction_default`, `jp_sbp_incoming_payments`). | +| **enabled** | `boolean` | Статус вебхука (`true` — включён, `false` — выключен). | +| **data** | `object` | Дополнительные данные (например, список `accounts`). | +| **callbackUri** | `string` | URL партнёра, на который будет отправлен вебхук. | +| **version** | `integer` | Версия формата данных. | + +**Пример JSON ответа:** + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 +} +``` + +--- + +## Ошибки + +| Код | Описание (error) | Описание ошибки (error_description) | +| :------ | :------------------------ | :-------------------------------------------------------------- | +| **400** | `invalid_request` | Неверные входные параметры запроса. | +| **401** | `invalid_token` | Токен просрочен, отозван или имеет неправильный формат. | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (настройки scope). | +| **403** | `insufficient_privileges` | Нет доступа к `callbackUri` или вебхуки выключены для партнёра. | +| **404** | `unknown_route` | Эндпоинт не найден или неактивен. | +| **429** | — | Too Many Requests (превышение лимита запросов). | +| **500** | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | — | Service Unavailable (сервис временно недоступен). | + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных выше. + +--- + +**Навигация:** +← [Как подключить](/products/alfa-api/documentation/articles/webhooks/articles/intro/intro) | [Редактирование вебхука](/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v1/edit-webhook) → + +]]> +
+ +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | + +--- + +## Пример запроса + +```bash +curl -X DELETE https://baas.alfabank.ru/api/v1/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3?object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### 200 — OK +Нет тела ответа. + +### 400 — Bad Request +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +### 401 — Unauthorized +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `invalid_token` — предоставленный токен просрочен, отозван или недействителен | +| **error_description** | string | optional | Описание ошибки | + +### 403 — Forbidden +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки:
• `insufficient_scope` — нет прав (настройки scope);
• `insufficient_privileges` — вебхуки выключены для клиента или сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 404 — Not Found +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `unknown_route` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +### 429 — Too Many Requests +Нет тела ответа. + +### 500 — Internal Server Error +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 503 — Service Unavailable +Нет тела ответа. + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в данной документации. + +--- +**Навигация:** +[← Редактирование вебхука](https://developers.alfabank.ru/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v2/edit-webhook) | [Получение вебхука →](https://developers.alfabank.ru/products/alfa-api/documentation/articles/webhooks/articles/get-webhook/v1/get-webhook) + +]]> +
+ +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей | +| **enabled** | `boolean` | optional | Статус: `true` (включён), `false` (выключен) | +| **organizationIdHash** | `string` | optional | Хэш идентификатора организации | +| **data** | `object` | optional | Дополнительные данные. Для `jp_sbp_incoming_payments` не заполняется. | +| **data.accounts** | `array of string`| optional | Список счетов. При `object: ul_transaction_default` — **обязательно** (передавать все счета). Пустой массив = вебхук на все счета. | +| **callbackUri** | `string` | optional | URL партнёра. Можно менять только `path`, менять `host` нельзя. | +| **version** | `integer` | optional | Версия формата данных. Допустимое значение — `1`. | + +--- + +## Пример запроса + +```bash +curl -X PUT https://baas.alfabank.ru/api/v2/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3 \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'X-Request-ID: {uuid}' \ + -d '{ + "object": "ul_transaction_default", + "enabled": true, + "data": { + "accounts": [ + "40802810401300015422", + "40802810401300015422" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1 + }' +``` + +--- + +## Параметры ответа + +### Пример ответа 200 (ОК) + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled by administrator" + } + ] +} +``` + +### Описание полей ответа (200 OK) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **id** | `uuid` | Идентификатор записи | +| **object** | `string` | Сущность подписки (`ul_transaction_default` или `jp_sbp_incoming_payments`) | +| **enabled** | `boolean` | Статус активации | +| **data.accounts** | `array` | Список счетов (для выписок) | +| **callbackUri** | `string` | URL получения уведомлений | +| **statusDescriptions** | `array` | Причины выключения вебхука (если есть) | + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав доступа; `insufficient_privileges` — нет доступа к callbackUri | +| **404** | Not Found | `unknown_route` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +> **Рекомендация:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- +[← Назад к списку: Редактирование вебхука v1](/products/alfa-api/documentation/articles/webhooks/articles/edit-webhook/v1/edit-webhook) | [Вперёд: Удаление вебхука →](/products/alfa-api/documentation/articles/webhooks/articles/delete-webhook/v1/delete-webhook) + +]]> +
+ +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | + +--- + +## Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/v2/webhooks/f9f8c674-7a2a-4297-bdb8-ddd3013de3a3?object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :--------------------- | :------------ | :------------------------------------------------------------------------ | +| **id** | uuid | Идентификатор записи | +| **object** | string | Объект подписки (`ul_transaction_default` или `jp_sbp_incoming_payments`) | +| **enabled** | boolean | Статус вебхука: `true` — включен, `false` — выключен | +| **organizationIdHash** | string | Хэш идентификатора организации | +| **data** | object | Дополнительные данные. Список полей зависит от события. | +| └ **accounts** | array[string] | Список счетов (для `ul_transaction_default`) | +| **callbackUri** | string | URL партнёра, на который отправляется вебхук | +| **version** | integer | Версия формата данных. Для текущих объектов значение — `1`. | +| **statusDescriptions** | array[object] | Описание статуса выключения вебхука | +| └ **cause** | string | Причина выключения | +| └ **description** | string | Описание причины | + +#### Пример ответа 200: + +```json +{ + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled administrator" + } + ] +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Ошибка (`error`) | +| :------ | :------------------ | :--------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (scope) | +| **404** | Not Found | `unknown_route` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +> **Рекомендация:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +_Документация Alfa API_ + +]]> +
+ +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей. | +| **offset** | integer | optional | Смещение в результатах поиска. | +| **limit** | integer | optional | Количество элементов на странице. | + +### Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/v2/webhooks?offset=20&limit=10&object=ul_transaction_default \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +#### Тело ответа (JSON) + +| Атрибут | Тип | Описание | +| :----------------------- | :------ | :---------------------------------------------------------------------------------------------------------- | +| **pagination** | object | Данные пагинации | +| ∟ **limit** | number | Количество объектов на одной странице | +| ∟ **offset** | number | Количество объектов в списке, которые необходимо пропустить | +| ∟ **totalCount** | number | Общее количество записей | +| **items** | array | Массив объектов результата | +| ∟ **id** | uuid | Идентификатор записи | +| ∟ **object** | string | Объект/сущность подписки (`ul_transaction_default`, `jp_sbp_incoming_payments`) | +| ∟ **enabled** | boolean | Статус вебхука: `true` — включён, `false` — выключен | +| ∟ **organizationIdHash** | string | Хэш идентификатора организации | +| ∟ **data** | object | Дополнительные данные. Поле **accounts** (array of string) заполняется при `object: ul_transaction_default` | +| ∟ **callbackUri** | string | URL партнёра, на который отправляется вебхук | +| ∟ **version** | integer | Версия формата данных (возможные значения — `1`) | +| ∟ **statusDescriptions** | array | Описание причин выключения вебхука | +| ∟∟ **cause** | string | Причина выключения | +| ∟∟ **description** | string | Описание причины | + +#### Пример ответа 200 + +```json +{ + "pagination": { + "offset": 45, + "limit": 10, + "totalCount": 100 + }, + "items": [ + { + "id": "f9f8c674-7a2a-4297-bdb8-ddd3013de3a3", + "object": "ul_transaction_default", + "enabled": true, + "organizationIdHash": "ff22df927f36344155f7075fae297541fcfca87e3dabef5aa9c951a21c4f072c", + "data": { + "accounts": [ + "40702810800000000001", + "40702810800000000004", + "40702810800000000007" + ] + }, + "callbackUri": "https://webhook.partner.ru/api/v1/webhook-events", + "version": 1, + "statusDescriptions": [ + { + "cause": "Revocation of agreement", + "description": "The webhook is disabled due to the agreement being revoked in Alfa ID" + }, + { + "cause": "Disabled by administrator", + "description": "Webhook disabled administrator" + } + ] + } + ] +} +``` + +--- + +## Ошибки + +| Код | Описание | Возможные `error` | +| :------ | :------------------ | :--------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (scope) | +| **404** | Not Found | `unknown_route` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа (превышен лимит запросов) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа (сервис временно недоступен) | + +> Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +**Навигация:** +← [Получение вебхука](/products/alfa-api/documentation/articles/webhooks/articles/get-webhook/v2/get-webhook) | [Партнёрский метод для получения вебхуков](/products/alfa-api/documentation/articles/webhooks/articles/partner-webhook/v1/partner-webhook) → + +]]> +
+ + **Важно:** Для предотвращения отправки Банком лишних retry-запросов необходимо возвращать коды, отличные от 2xx, только при возникновении технических сбоев на стороне партнёра. + +### **Выписки** + +В сервисе ["Выписки по счетам юрлиц"](/products/alfa-api/documentation/articles/transactions/transactions) в методах есть уникальный идентификатор транзакции (`transactionId`). Важно, чтобы партнёр на своей стороне игнорировал задублированные сообщения по этому идентификатору, возвращая код успешной обработки (2xx). + +### **Входящие платежи по СБП для юрлиц** + +В методе ["Получение входящих платежей"](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2b/articles/incoming-payments/v1/incoming-payments) есть уникальный идентификатор операции НСПК (`nspkTransactionId`). Важно игнорировать задублированные сообщения по этому идентификатору, возвращая код успешной обработки (2xx). + +--- + +## Параметры запроса (BODY) + +| Атрибут | Тип | Обязательность | Описание | +| :----------------- | :----- | :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **actionType** | string | required | Действие над объектом. Возможные значения: `create` (создание), `update` (обновление), `delete` (удаление). | +| **eventTime** | string | required | Время, когда произошло событие. | +| **object** | string | required | Объект/сущность подписки: `ul_transaction_default` (выписка), `jp_sbp_incoming_payments` (входящие платежи СБП). | +| **data** | object | required | Данные по вебхукам. Поля зависят от объекта (см. методы [«Получение выписки»](/products/alfa-api/documentation/articles/transactions/articles/statement/v1/statement) или [«Получение входящих платежей»](/products/alfa-api/documentation/articles/sbp/articles/sbp-b2b/articles/incoming-payments/v1/incoming-payments)). | +| **organizationId** | string | optional | Идентификатор организации. | +| **sub** | string | optional | Идентификатор субъекта. | + +--- + +## Пример запроса + +```bash +curl -X POST https://webhook.partner.ru/api/v1/webhook-events \ +-H "Content-Type: application/json" \ +-d '[ + { + "actionType": "create", + "eventTime": "2022-01-12T00:00:00", + "object": "ul_transaction_default", + "organizationId": "vvvvvv", + "sub": "f7490296-1ae1-11ec-9621-0242ac130002", + "data": { + "amount": { + "amount": 1.00, + "currencyName": "RUR" + }, + "amountRub": { + "amount": 1.00, + "currencyName": "RUR" + }, + "correspondingAccount": "30101810200000000593", + "direction": "CREDIT", + "documentDate": "2022-01-12", + "filial": "АО \"АЛЬФА-БАНК\" г Москва", + "number": "178", + "operationCode": "01", + "operationDate": "2022-01-12T00:00:00", + "paymentPurpose": "Перевод собственных средств. НДС не облагается.", + "priority": "5", + "revaln": null, + "uuid": "9084d309-b30b-5083-9a54-d4522472e11a", + "transactionId": "1220112MOCO#DS4001415", + "rurTransfer": { + "cartInfo": { + "documentCode": null, + "documentContent": null, + "documentDate": null, + "documentNumber": null, + "paymentNumber": null, + "restAmount": null + }, + "deliveryKind": "электронно", + "departmentalInfo": { + "uip": "1", + "drawerStatus101": "01", + "kbk": "18210102010011000110", + "oktmo": "12301000", + "reasonCode106": "ТП", + "taxPeriod107": "ГД.01.2022", + "docNumber108": "123", + "docDate109": "12.01.2022", + "paymentKind110": "1" + }, + "payeeAccount": "40702810301300000763", + "payeeBankBic": "044525593", + "payeeBankCorrAccount": "30101810200000000593", + "payeeBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payeeInn": "0140237176", + "payeeKpp": "770801001", + "payeeName": "Полное наименование Орг № 11329", + "payerAccount": "40702810701300000761", + "payerBankBic": "044525593", + "payerBankCorrAccount": "30101810200000000593", + "payerBankName": "АО \"АЛЬФА-БАНК\" г Москва", + "payerInn": "0140237176", + "payerKpp": "770801001", + "payerName": "Полное наименование Орг № 11329", + "payingCondition": null, + "purposeCode": "2", + "receiptDate": "2022-01-12", + "valueDate": "2022-01-12" + } + } + } +]' +``` + +--- + +## Параметры ответа + +В случае успешной обработки ответа на стороне клиента необходимо вернуть любой код успешной обработки (**2xx**). + +]]> + + + **Важно** +> Для создания вебхука с другим хостом необходимо удалить уже существующий вебхук. + +--- + +### Допустимые значения scope + +| Событие | scope | +| :-------------------------------- | :------------- | +| Операции по счетам | `transactions` | +| Входящие платежи по СБП для юрлиц | `b2b-sbp` | + +--- + +**Дополнительные материалы:** + +- **Предыдущая тема:** [Шифрование TXT ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/text-gost/text-gost) +- **Следующая тема:** [Создание вебхука](/products/alfa-api/documentation/articles/webhooks/articles/create-webhook/v1/create-webhook) +- **Видео-инструкция:** [Смотреть MP4](/assets/developers-portal.docs.alfa-api/articles/webhooks/articles/intro/files/webhooks.mp4) + +]]> + + +<Обмен_файлами> + + + + + + + + + + +<Общая_информация> + + + + + + + + + + + + + + + + +`GET /jp/v2/accounts/{accountNumber}/transactions/1C`
`GET /jp/v1/accounts/{accountNumber}/transactions/MT940`
`GET /jp/v1/correspondent-accounts/{accountNumber}/transactions`
`GET /jp/v1/statement/summary`
`POST /jp/v1/accounts/{accountNumber}/transactions/files/requests`
`GET /jp/v1/accounts/transactions/files/requests/{requestId}` | +| escrow | Эскроу-счета 214-ФЗ. Резервирование | `GET /build-projects`
`POST /escrow-orders`
`GET /jp/v1/escrow-orders/{referenceID}`
`GET /jp/v1/escrow-orders`
`PATCH /escrow-orders/{referenceID}/execute`
`DELETE /escrow-orders/{referenceID}`
`POST /jp/v1/escrow-orders/{referenceID}/cancel`
`POST /jp/v1/escrow-orders-full` | +| escrow-reports | Эскроу-счета 214-ФЗ. Формирование отчётов | `GET /jp/v1/escrow-reports/developers/build-projects`
`POST /jp/v1/escrow-reports` | +| customer | Профиль организации | `GET /jp/v2/customer-info` | +| payment | Платёжные поручения | `POST /jp/v2/payments`
`GET /jp/v2/payments/{externalId}/state`
`GET /jp/v1/payments/{externalId}`
`GET /jp/v1/payments/{externalId}/print-form`
`GET /jp/v1/payments/{externalId}/print-form/download`
`PATCH /jp/v2/payments/{externalId}/state` | +| as-operation-with-selfemployed | Добавление самозанятых, получение справочных данных | `POST /semp/v1/agreement-pages`
`POST /semp/v1/selfemployed/registries/add-selfemployed`
`GET /semp/v1/selfemployed/registries/add-selfemployed/{requestId}`
`GET /semp/v1/dictionary/activities`
`GET /semp/v1/dictionary/regions`
`GET /semp/v1/selfemployed/lists`
`GET /semp/v1/selfemployed/{vatin}`
`PUT /semp/v1/selfemployed/{vatin}` | +| as-selfemployed-fts-status | Статус самозанятого | `POST /semp/v1/selfemployed/taxpayer-statuses`
`GET /semp/v1/selfemployed/taxpayer-statuses/{requestId}` | +| as-accrual-and-debt | Налоговые начисления, задолженности и пени самозанятого | `POST /semp/v1/selfemployed/accruals-and-debts`
`GET /semp/v1/selfemployed/accruals-and-debts/{requestId}`
`POST /semp/v1/selfemployed/payment-documents`
`GET /semp/v1/selfemployed/payment-documents/{requestId}`
`POST /semp/v1/selfemployed/income-for-period`
`GET /semp/v1/selfemployed/income-for-period/{requestId}`
`POST /semp/v1/selfemployed/income`
`GET /semp/v1/selfemployed/income/{requestId}`
`POST /semp/v1/selfemployed/taxpayer-account-info`
`GET /semp/v1/selfemployed/taxpayer-account-info/{requestId}` | +| as-receipt-and-payout | Проведение выплат и формирование чеков, список банков-участников СБП | `POST /semp/v1/payouts/registries/receipts-and-payouts`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/cancel-receipts`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-receipt | Декларация доходов, аннулирование чеков | `POST /semp/v1/payouts/registries/receipts`
`POST /semp/v1/payouts/registries/cancel-receipts`
`GET /semp/v1/payouts/registries/cancel-receipts/{requestId}`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-payout-with-check-status | Проведение выплат самозанятым, список банков-участников СБП | `POST /semp/v1/payouts/registries/with-selfemployed-check-status`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| as-payout | Осуществление выплат самозанятым | `POST /semp/v1/payouts/registries/payouts`
`GET /semp/v1/payouts/registries/{requestId}`
`GET /semp/v1/payouts`
`GET /semp/v1/dictionary/sbp-banks`
`GET /semp/v1/payouts/lists`
`GET /semp/v1/payouts/selfemployed/{vatin}`
`POST /semp/v1/payouts/registries/accept/{requestId}` | +| sbp_terminals_reg | Приём оплаты через СБП | `GET /jp/v1/legal`
`GET /jp/v1/merchants/{merchantId}`
`POST /jp/v1/terminals` | +| loan-applications | Кредиты | `POST /smart-loans/jp/v1/loan-applications`
`POST /loan-applications`
`GET /smart-loans/jp/v1/loan-applications/{dealId}/status` | +| signature | Электронная подпись | `GET /jp/v3/signature/dn`
`GET /jp/v3/signature/dn/file`
`POST /jp/v3/signature/rsa-certificates/requests/issue`
`POST /jp/v3/signature/requests/{id}/operations`
`PUT /jp/v3/signature/requests/operations/{id}`
`GET /jp/v3/signature/requests/{id}`
`GET /jp/v3/signature/rsa-certificates/{id}`
`POST /jp/v3/signature/rsa-certificates/{id}/requests/activation`
`PUT /jp/v3/signature/sign-settings`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/switch`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/reissue`
`POST /jp/v3/signature/rsa-certificates/{Id}/requests/revocation`
`POST /jp/v3/signature/qes/requests`
`POST /jp/v3/signature/qes/requests/{Id}`
`PATCH /jp/v3/signature/qes/requests/{Id}`
`POST /jp/v3/signature/powers-of-attorney/requests`
`GET /jp/v3/signature/powers-of-attorney/requests/{id}/status`
`GET /jp/v3/signature/powers-of-attorney/requests/{id}` | +| accounts | Счета | `GET /pp/v1/accounts`
`GET /pp/v1/accounts/{accountNumber}`
`GET /pp/v1/accounts/{accountNumber}/requisites`
`GET /jp/open-banking/v1.3/accounts`
`GET /jp/open-banking/v1.3/accounts/{accountId}/statements`
`POST /jp/open-banking/v1.3/statements`
`GET /jp/open-banking/v1.3/statements/{statementId}` | +| cards | Карты | `GET /pp/v1/cards`
`GET /pp/v1/cards/{cardId}/tariffs`
`GET /pp/v1/cards/{cardId}/subscriptions` | +| card-sec-actions | Тарифы и операции по карте | `GET /pp/v1/cards/{cardId}/actions`
`POST /pp/v1/cards/{cardId}/actions`
`PUT /pp/v1/cards/{cardId}/actions` | +| operations-history | Истории операций | `GET /pp/v1/operations`
`GET /pp/v1/operations/{id}` | +| reports-downloading | Получение документов | `GET /pp/v1/reports`
`GET /pp/v1/reports/{reportId}/body` | +| debit-statements | Выписки по счёту | `POST /pp/v1/reports/type/account`
`POST /pp/v1/reports/type/account/balance/eng`
`POST /pp/v1/reports/type/account/balance/rus` | +| credit-statements | Справки по кредитам | `POST /pp/v1/reports/type/credit/closed`
`POST /pp/v1/reports/type/credit/info`
`POST /pp/v1/reports/type/credit/statement` | +| deposit-statements | Справка по депозиту | `POST /pp/v1/reports/type/deposit` | +| limits-control | Лимиты по операциям | `GET /pp/v1/limits/general`
`GET /pp/v1/cards/{cardId}/user-limits`
`POST /pp/v1/cards/{cardId}/user-limits`
`DELETE /pp/v1/cards/{cardId}/user-limits/{limitId}` | +| loyalty | Программа лояльности | `POST /pp/v1/bonus-accounts-transactions`
`GET /pp/v1/bonus-accounts`
`GET /pp/v1/bonus-accounts/{accountNumber}` | +| b2c_sbp_payments | Платежи через СБП | `POST /b2cpay/jp/v1/payments`
`GET /b2cpay/jp/v1/payments`
`GET /b2cpay/jp/v1/payments/packages/{packageId}`
`POST /b2cpay/jp/v1/clients/checks`
`GET /b2cpay/jp/v1/clients/checks/{checkId}`
`GET /b2cpay/jp/v1/clients/info`
`GET /b2cpay/jp/v1/banks`
`GET /b2cpay/jp/v1/payments/download/{transactionId}` | +| credit | Кредитные предложения | `GET /pp/v1/credit-offers` | +| c2b-sbp | Оплата покупок через СБП | `POST /sbp/jp/v1/qrcs`
`POST /sbp/jp/v1/subscriptions`
`GET /sbp/jp/v1/qrc-status`
`POST /sbp/jp/v1/petitions`
`POST /sbp/jp/v1/terminals/{termNo}/cash-qrcs`
`POST /sbp/jp/v1/terminals/{termNo}/cash-qrcs/{qrcId}/activation`
`DELETE /sbp/jp/v1/terminals/{termNo}/cash-qrcs/{qrcId}/activation`
`POST /sbp/jp/v1/refund`
`GET /sbp/jp/v1/refund/status` | +| b2b-sbp | Операции СБП для юрлиц | `POST /sbp/jp/v1/payment-urls/one-time-use`
`POST /sbp/jp/v1/payment-urls/reusable`
`GET /sbp/jp/v1/payment-urls`
`GET /sbp/jp/v1/payment-urls/{qrcId}/data`
`GET /sbp/jp/v1/incoming-payments`
`POST /sbp/jp/v1/outgoing-payments/one-pay`
`GET /sbp/jp/v1/outgoing-payments`
`GET /sbp/jp/v1/outgoing-payments/{outgoingPaymentId}/status`
`POST /sbp/jp/v1/payment-urls/batch`
`GET /sbp/jp/v1/payment-urls/batch/{batchId}`
`PATCH /sbp/jp/v1/payment-urls` | +| digital-tariff | Дебетовая анкета | `POST /pp/v1/debit-cards/forms`
`POST /pp/v1/debit-cards/forms/{formId}/verification-sms`
`POST /pp/v1/debit-cards/forms/{formId}/resending-sms`
`POST /pp/v1/debit-cards/forms/{formId}/verification-passport` | +| plastic-delivery | Доставка дебетовой карты | `POST /pp/v1/debit-cards/forms/{formId}/verification-sms`
`POST /pp/v1/debit-cards/forms/{formId}/resending-sms`
`GET /pp/v1/debit-cards/forms/{formId}/draft`
`GET /pp/v1/debit-cards/forms/{formId}/delivery-type`
`GET /pp/v1/debit-cards/forms/{formId}/time-slots`
`POST /pp/v1/debit-cards/forms/{formId}/time-slots`
`POST /pp/v1/debit-cards/forms/{formId}/confirmation` | +| dfa | Цифровые финансовые активы (ЦФА) | `GET /dfa/gd/v1/dfa-profile/initial-placement-list` | +| salary-project | Зарплатный проект | `POST /jp/v1/salary-project/accounts/applications`
`GET /jp/v1/salary-project/accounts/applications/{applicationId}`
`POST /jp/v1/salary-project/payroll/applications`
`GET /jp/v1/salary-project/payroll/applications/{applicationId}` | +| loyalty-program | Получение бонусных номеров | `GET /pp/v1/bonus-numbers` | +| payment-registries | Реестры рублёвых платежей | `POST /jp/v2/payments/registries`
`GET /jp/v2/payments/registries/{registryId}` | +| invoices | Выставление счёта клиенту | `POST /jp/v1/payments/from-invoice`
`POST /jp/v2/payments/from-invoice-budget` | +| factoring | Факторинг | `GET /aff/jp/v1/creditors/compliance`
`POST /aff/jp/v1/payments`
`POST /aff/jp/v1/registers`
`POST /aff/jp/v1/registers/sign`
`GET /aff/jp/v1/payments/{paymentId}`
`GET /aff/jp/v1/registers/{registerId}`
`GET /aff/jp/v1/registers/{registerId}/documents` | +| beneficiaries | Информация о номинальных счетах и их контрагенты | `GET /na/jp/v1/nominal-accounts`
`GET /na/jp/v1/beneficiaries/requests/{requestId}/status`
`POST /na/jp/v1/beneficiaries`
`GET /na/jp/v1/beneficiaries`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}`
`PUT /na/jp/v1/beneficiaries/{beneficiaryId}`
`POST /na/jp/v1/beneficiaries/{beneficiaryId}/scoring`
`POST /na/jp/v1/beneficiaries/{beneficiaryId}/requisites`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/requisites`
`PATCH /na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/balance`
`GET /na/jp/v1/beneficiaries/{beneficiaryId}/transactions`
`POST /na/jp/v1/universal-recipients`
`GET /na/jp/v1/universal-recipients`
`GET/na/jp/v1/universal-recipients/{universalRecipientId}`
`POST /na/jp/v1/universal-recipients/{universalRecipientId}/requisites`
`GET /na/jp/v1/universal-recipients/{universalRecipientId}/requisites`
`PATCH /na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}` | +| deals | Безопасные сделки | `POST /na/jp/v1/deals`
`GET /na/jp/v1/deals`
`GET /na/jp/v1/deals/{dealId}`
`PATCH /na/jp/v1/deals/{dealId}/is-valid`
`GET /na/jp/v1/deals/{dealId}/payoffs`
`PATCH /na/jp/v1/deals/action`
`POST /na/jp/v1/deals/steps`
`GET /na/jp/v1/deals/{dealId}/requests/{requestId}/status`
`GET /na/jp/v1/deals/{dealId}/steps`
`GET /na/jp/v1/deals/{dealId}/steps/{stepId}`
`PATCH /na/jp/v1/deals/steps/contractors`
`GET /na/jp/v1/deals/{dealId}/steps/{stepId}/contractors` | +| beneficiary-payments | Идентификация пополнений номинального счёта и выплаты с него | `GET /na/jp/v1/unidentified-transactions`
`POST /na/jp/v1/unidentified-transactions/{id}/identify`
`GET /na/jp/v1/unidentified-transactions/{id}/identify/{identifyId}`
`POST /na/jp/v1/unidentified-transactions/{id}/refunds`
`GET /na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}`
`POST /na/jp/v1/payoffs`
`GET /na/jp/v1/payoffs/{payoffId}/status`
`PATCH /na/jp/v1/payoffs/{payoffId}/accept`
`GET /na/jp/v1/payoffs/{payoffId}`
`POST /na/jp/v1/tax-refund`
`GET /na/jp/v1/tax-refund/{taxRefundId}/status`
`PATCH /na/jp/v1/tax-refund/{taxRefundId}/accept` | + + +]]> +
+ + + + + + +<Сертификаты_Минцифры> + + + + + «Terminal», чтобы открыть терминал. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux1.png) + +2. Убедитесь, что файлы сертификатов «russian_trusted_root_ca_pem.crt» и «russian_trusted_sub_ca_pem.crt» находятся в директории «Downloads». Для проверки перейдите в неё с помощью `cd` и вызовите команду `ls` для отображения списка файлов. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux2.png) + +3. Скопируйте корневой сертификат в каталог `/usr/share/pki/ca-trust-source/anchors/` . Выполните команду `sudo cp russian_trusted_root_ca_pem.crt /usr/share/pki/ca-trust-source/anchors` . + +4. Введите пароль суперпользователя. + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux3.png) + +5. Cкопируйте в этот же каталог выпускающий сертификат. Выполните команду `sudo cp russian_trusted_sub_ca_pem.crt /usr/share/pki/ca-trust-source/anchors` . + +6. Обновите общесистемное хранилище сертификатов командой `sudo update-ca-trust` . + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux4.png) + +7. Проверьте хранилище доверенных сертификатов. Воспользуйтесь командой `trust list` . В конце списка должны появиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +## Mozilla Firefox + +1. **Скачайте сертификаты** +Скачайте [«корневой сертификат»](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_root_ca_pem.crt) и [«выпускающий сертификат»](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_sub_ca_pem.crt). Загрузите сертификаты в папку «Downloads». + +2. **Установите сертификаты Удостоверяющего Центра Минцифры** +1. Откройте браузер Firefox → перейдите в «Настройки» → в поиске введите «Сертификат» → выберите «Просмотр сертификатов…». + +2. В открывшемся окне «Управление сертификатами» нажмите на «Импортировать…». + +3. Перейдите в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_root_ca_pem.crt» → установите флажок «Доверять при идентификации веб-сайтов» → нажмите «ОК». + +4. В открывшемся окне «Управление сертификатами» нажмите «Импортировать». + +5. Вернитесь в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_sub_ca_pem.crt» → установите флажок «Доверять при идентификации веб-сайтов» → нажмите «ОК». + +6. Проверьте список сертификатов. Найдите в нём «The Ministry of Digital Development and Communications». Внутри должны находиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux5.png) + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +## Chromium + +1. **Скачайте сертификаты** +Скачайте [](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_root_ca_pem.crt) и [](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/russian_trusted_sub_ca_pem.crt). Загрузите сертификаты в папку «Downloads». + +2. **Установите сертификаты Удостоверяющего Центра Минцифры** +1. Откройте браузер Chromium → перейдите в «Настройки» → в строке поиска введите «Сертификат» → нажмите на «Безопасность» в разделе «Конфиденциальность и безопасность» → выберите «Настроить сертификаты». + +2. Перейдите во вкладку «Центры сертификации» → выберите «Импорт». + +3. Перейдите в папку со скачанными сертификатами. Дважды кликните по сертификату «russian_trusted_root_ca_pem.crt» → установите флажок «Доверять этому сертификату при идентификации сайтов» → нажмите «ОК». + +4. Во вкладке «Центры сертификации» снова выберите кнопку «Импорт» → дважды кликните по сертификату «russian_trusted_sub_ca_pem.crt» → установите флажок «Доверять этому сертификату при идентификации сайтов» → нажмите «ОК». + +5. Проверьте список сертификатов. Найдите «org-The Ministry of Digital Development and Communications» и раскройте список. Внутри должны находиться сертификаты «Russian Trusted Root CA» и «Russian Trusted Sub CA». + +![image](https://developers.alfabank.ru/assets/developers-portal.docs.alfa-api/articles/specification/articles/certificate/articles/linux/files/linux6.png) + +Очистите кэш вашего браузераОчистите кэш браузера на устройстве, с которого осуществляется доступ. Это необходимо для корректной работы с ресурсами, защищёнными сертификатами безопасности Минцифры. + +[Сертификаты для MacOS](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/macos/macos)[Как подключить](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/instruction/instruction) +]]> + + + + + + +<Песочница> + + +• `ul_transaction_default` — получение выписки;
• `jp_sbp_incoming_payments` — получение входящих платежей | + +### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/v1/webhooks-events \ + -H 'Authorization: Bearer {token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "object": "ul_transaction_default" + }' +``` + +--- + +## Параметры ответа + +### 201 Created + +Нет тела ответа. + +### 400 Bad Request + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :--------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +### 401 Unauthorized + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `invalid_token` — предоставленный токен просрочен, отозван, имеет неправильный формат или недействителен | +| **error_description** | string | optional | Описание ошибки | + +### 403 Forbidden + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `insufficient_scope` — у пользователя нет прав на использование запрашиваемого сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 404 Not Found + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `unknown_route` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +### 429 Too Many Requests + +Нет тела ответа. + +### 500 Internal Server Error + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------- | +| **error** | string | required | Код ошибки. Значение: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +### 503 Service Unavailable + +Нет тела ответа. + +> **Примечание:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +## Навигация + +- ← [Инструкция по тестированию](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/intro/intro) +- [Тестирование электронной подписи](/products/alfa-api/documentation/articles/sandbox/articles/check-signature/check-signature) → + +]]> +
+ + + +
+ + + + + + + + **Внимание** +> Обработка негативных сценариев (например, ошибки валидации или доступа) **в песочнице** может отличаться от обработки в промышленной среде и спецификации тестируемого метода. + +--- + +## Подготовка к работе в песочнице + +Для начала работы в песочнице пройдите следующие шаги: + +1. **Заключите договор о техническо-информационном взаимодействии** + Подробнее [на странице Подписание договора](/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding). + +2. **Получите тестовый `client_id` и `scope`** + Получите `client_id` и доступные `scope` [на Портале разработчика](/products/alfa-api/documentation/articles/selfservice/articles/test/test). Также эти данные можно найти в письме, отправленном банком вам на почту после подписания договора. + +3. **Установите тестовый TLS-сертификат** + Для получения доступа к тестовой среде необходимо установить тестовый TLS-сертификат – [test_cert.zip](/assets/developers-portal.docs.alfa-api/articles/sandbox/articles/intro/files/test_cert.zip) – пароль для архива уточняйте у персонального менеджера. + + **Архив состоит из файлов:** + - `sandbox_cert_2026.cer` – сертификат для клиента (открытый ключ); + - `sandbox_key_2026.key` – закрытый ключ; + - `apica_2022_chain.cer` – цепочка сертификатов УЦ (содержит в себе `root_apica_2022.cer` и `sub_root_apica_2022.cer`); + - `root_apica_2022.cer` – корневой сертификат УЦ; + - `sub_root_apica_2022.cer` – промежуточный сертификат УЦ; + - `baas_swagger_2026.p12` – контейнер p12, содержащий вышеперечисленные файлы. + + Для доступа к Swagger UI можно использовать следующие комбинации (в зависимости от выбора Вашего ПО для работы с API): + - открытый ключ + закрытый ключ + цепочка сертификатов УЦ; + - открытый ключ + закрытый ключ + корневой сертификат УЦ + промежуточный сертификат УЦ; + - контейнер p12 (`baas_swagger_2026.p12`) – самый простой способ. + + **Важно!** Корневой сертификат УЦ необходимо добавить в доверенные сертификаты на своей стороне. + + Для вызова методов можно использовать стандартные программные средства для работы с API: Postman, SoapUI, JMeter, curl или использовать самописные программные средства или встроенные возможности ERP-системы. + +4. **Установите сертификаты Минцифры** + Для корректной работы песочницы необходимо установить [сертификаты Минцифры](/products/alfa-api/documentation/articles/specification/articles/certificate/articles/intro/intro). + +5. **Проверьте тестовый Swagger UI** + Тестовый Swagger UI находится по адресу [https://sandbox.alfabank.ru/swagger-ui/](https://sandbox.alfabank.ru/swagger-ui/) + +6. **Получите тестовый `client_secret`** + Подробнее [на странице Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret). + +--- + +## Особенности вызовов + +После выполнения указанных шагов вы можете приступать к тестированию запросов в песочнице. + +При использовании песочницы все вызовы API должны осуществляться с установкой mTLS-соединения. В зависимости от требований используемого вами клиента при отправке запросов вам может понадобиться сертификат и закрытый ключ. Рекомендуем ознакомиться с документацией используемого клиента. + +### Пример запроса (cURL) + +```bash +curl -X GET https://sandbox.alfabank.ru/api/v1/endpoint \ + -v --cert test_certificate.cer \ + --key test_key.key \ + --header 'accept: application/json' \ + --header 'content-type: application/json' +``` + +--- + +## Как сообщить об ошибке + +Отправьте письмо на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru), указав следующие данные: + +1. `client_id`. +2. Дата и время запроса с указанием часового пояса. +3. Метод и URI запроса. +4. Заголовки и тело запроса. +5. Полученная ошибка и заголовки ответа, включая `X-TraceId`. +6. IP-адрес, с которого был отправлен запрос. + +--- + +## Адреса для тестирования + +- **Получение кода авторизации:** [https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}&scope={scope}&state={state}](https://id-sandbox.alfabank.ru/oidc/authorize?response_type=code&client_id=%7Bclient_id%7D&redirect_uri=%7Bredirect_uri%7D&scope=%7Bscope%7D&state=%7Bstate%7D) +- **Другие запросы в Alfa ID:** [https://sandbox.alfabank.ru/oidc](https://sandbox.alfabank.ru/oidc) +- **Запросы в Alfa API:** [https://sandbox.alfabank.ru/api](https://sandbox.alfabank.ru/api) + +--- + +## Счета для тестирования + +**Номера счетов:** + +- `40702810102300000001` +- `40702810402300000002` +- `40702810002300000003` +- `40702810002300000004` + +**Номер корреспондентского счёта:** + +- `30102810102300000593` + +--- + +## Рекомендации по тестированию Alfa ID ЮЛ (Юридические лица) + +Для прохождения процедуры аутентификации используйте тестовые данные: + +- **Login:** `SomeDifficultLogin` +- **Password:** `1qaz!QAZ` +- **One-Time Password (OTP):** `000000` + +Для подписания формы согласия используйте: + +- **One-Time Password:** `111111` + +Подробнее [в разделе Alfa ID](/products/alfa-api/documentation/articles/alfa-id/alfa-id). + +--- + +## Рекомендации по тестированию Alfa ID ФЛ (Физические лица) + +Для прохождения процедуры аутентификации используйте тестовые данные: + +- **Номер телефона:** `71111111111` +- **Login:** `SomeDifficultLogin` +- **Password:** `000000` +- **One-Time Password (OTP):** `000000` + +Для подписания формы согласия используйте: + +- **One-Time Password:** `000000` + +Подробнее [в разделе Alfa ID](/products/alfa-api/documentation/articles/alfa-id/alfa-id). + +--- + +[← API Key](/products/alfa-api/documentation/articles/api-key/api-key) | [Инструкция по тестированию вебхуков →](/products/alfa-api/documentation/articles/sandbox/articles/check-webhook/articles/intro/intro) + +]]> + + + + + + + **Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке Вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------------- | :----- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/jose | +| **Content-Type** | string | required | application/jose | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты канала для запроса. Значения: `NO` (без защиты), `SIGNATURE` (проверка подписи), `ENCRYPTION` (дешифрование и проверка подписи). | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты канала для ответа. Значения: `NO` (без защиты), `SIGNATURE` (подписание ответа), `ENCRYPTION` (подписание и шифрование ответа). | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------ | :----- | :------------- | :-------------------------------- | +| (root) | string | required | Тело подписи в виде base64-строки | + +--- + +### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/json \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/jose' \ + -H 'Content-Type: application/jose' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### 201 Created + +| Атрибут | Тип | Обязательность | Описание | +| :------ | :----- | :------------- | :---------- | +| (root) | string | optional | Тело ответа | + +#### 400 Bad Request + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :----------------------------------------------------------------- | +| **error** | string | required | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | optional | Описание ошибки | + +#### 401 Unauthorized + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------------------------ | +| **error** | string | required | Код ошибки: `invalid_token` — токен просрочен, отозван или недействителен | +| **error_description** | string | optional | Описание ошибки | + +#### 404 Not Found + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :---------------------------------------------------------------- | +| **error** | string | required | Код ошибки: `unknown_endpoint` — эндпоинт не найден или неактивен | +| **error_description** | string | optional | Описание ошибки | + +#### 500 Internal Server Error + +| Атрибут | Тип | Обязательность | Описание | +| :-------------------- | :----- | :------------- | :------------------------------------------------------- | +| **error** | string | required | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description** | string | optional | Описание ошибки | + +--- + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации._ + +--- + +**Навигация:** + +- [← Управление сертификатами для подписи и шифрования](/products/alfa-api/documentation/articles/sandbox/articles/managing-certificates/managing-certificates) +- [Формат исходного сообщения XML →](/products/alfa-api/documentation/articles/sandbox/articles/signature/articles/xmldsig/v1/xmldsig) + +]]> + + + **⚠️ Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения настроек или их изменения напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru), указав способ защиты (подпись или подпись с шифрованием) и алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | text/plain | +| **Content-Type** | string | required | text/plain | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты запроса. Значения: `NO` (без защиты), `SIGNATURE` (подпись), `ENCRYPTION` (дешифрование и подпись). | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты ответа. Значения: `NO` (без защиты), `SIGNATURE` (подпись), `ENCRYPTION` (подпись и шифрование). | + +#### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| — | string | required | Тело подписи в виде base64-строки | + +#### Пример запроса +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/text \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: text/plain' \ + -H 'Content-Type: text/plain' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### 201 Created +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **responseTextFiled** | string | optional | Тело ответа | + +**Пример ответа:** +```text +responseTextFiled:responseTextValue +``` + +#### Ошибки (400, 401, 404, 500) +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | required | Код ошибки (например, `invalid_request`, `invalid_token`, `unknown_endpoint`, `internal_error`) | +| **error_description** | string | optional | Детальное описание ошибки | + +--- +*Примечание: Значения параметров ошибок могут изменяться. Рекомендуется предусмотреть стандартную обработку ошибок.* + +]]> + + + **Внимание** +> Способ защиты данных определяется настройками интеграции. Для уточнения информации по настройке вашей интеграции или запроса для установления нужных настроек необходимо написать на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). При запросе установления настроек необходимо сообщить способ защиты (подпись или подпись с шифрованием), а также алгоритм (RSA или ГОСТ). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------------- | :----- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------ | +| **Authorization** | string | required | Bearer {access_token} | +| **Accept** | string | required | application/xml | +| **Content-Type** | string | required | application/xml | +| **X-Request-ChannelSecurity** | string | optional | Тип защиты канала для запроса. Значения: `NO` — без защиты; `SIGNATURE` — проверка подписи; `ENCRYPTION` — дешифрование и проверка подписи. | +| **X-Response-ChannelSecurity** | string | optional | Тип защиты канала для ответа. Значения: `NO` — без защиты; `SIGNATURE` — подписание ответа; `ENCRYPTION` — подписание и шифрование. | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :----- | :------------- | :-------------------------------- | +| (тело запроса) | string | required | Тело подписи в виде base64-строки | + +#### Пример запроса + +```bash +curl -X POST https://sandbox.alfabank.ru/api/signature-encryption-tests/xml \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/xml' \ + -H 'Content-Type: application/xml' \ + -H 'X-Request-ChannelSecurity: SIGNATURE' \ + -H 'X-Response-ChannelSecurity: SIGNATURE' \ + -d 'eyJraWQiOiI2MTAwMDM4YWFhYTAxZTRkN2YzOTM5OGQ4NDAwMDEwMDAzOGFhYSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJjb3VudCI6MTAwLCJzb21lRmllbGQiOiJzb21lVmFsdWUiLCJpZCI6IjNiNzk1YTBlLTFjOTctNDIxMi05YTI4LWYyODJkODAxNWI1YSIsImNyZWF0aW9uRGF0ZSI6IjIwMjItMDUtMThUMTA6Mjc6MDkuNzEyWiIsInN0YXR1cyI6ImFjdGl2ZSJ9.WYQKfllUHfs7IN0DdujjKlqpnThfJZgY_A6CZN-ghFohTYbDiRAJBAk4IxIkRfj2Hxcz4rR5DEKX8remdXEOHGrBpNf4okOob0bfIutNRhaeaZAIMFKjungALPRBmMhAiU0t5-Vp3ImUwhidSnSSP08gCHrTD1by5zYrzzYBB6tyikf8lNwYJQKRxscZcXqwOU9gAWBuV4rteClIbDCeTwkx5ci6WKWAq8bv7RDuwU_1KPjh6upJmwJ1g1epmvPdaFOQq5uf9NhAxomeeptmJoBOm3c8ZSYASYMno8KNWxr94B2xAhD7NCakfFCiQZjSH9b6MjM2aJEBhDyKYo2IGw' +``` + +--- + +### Параметры ответа + +#### Успешный ответ (201 Created) + +| Атрибут | Тип | Описание | +| :---------------------------- | :----- | :---------------------------------------------------------------- | +| **ds:Signature** | string | Корневой элемент XML Signature | +| **ds:SignedInfo** | string | Содержит информацию об алгоритме канонизации, подписи и дайджесте | +| **ds:CanonicalizationMethod** | string | Алгоритм канонизации (атрибут `Algorithm`) | +| **ds:SignatureMethod** | string | Алгоритм подписи (атрибут `Algorithm`) | +| **ds:DigestMethod** | string | Алгоритм дайджеста (атрибут `Algorithm`) | +| **ds:SignatureValue** | string | Значение тела подписи в кодировке base64 | +| **ds:KeyInfo** | string | Информация о ключах и сертификатах для проверки подписи | +| **ds:X509Data** | string | Информация о сертификатах | +| **ds:X509Certificate** | string | Сертификат, которым подписано тело, в base64 | + +#### Пример ответа 201 + +```xml + + + XmlElementValue2 + + H6jGW+bKLwvQ9xxbhZ6jNYRHtupT4aJ4jjlLh4W8svK0w5G7ZXf4OxqRR0t2l6aYOpNBdN2Q0+2T +1LXyadtnz7XJ7QYXNXrnWNcq7mOxM5Lj5bBQa2JPZSiMkp1lsnAV/LFDAJ+Uhruj3mFQxjiFpJLR +W/vRJzmRv925xXWopb94PFvP9mjtAwPXtBGEL5rqJICabzVo8+1BfPwFF5+8sqYzT74mmJIQmeFm +FiYVMNive5lRxlt7nXEgS4iENF1dXq5+prCPloms8hIX6I4HQo3Jn+G37Os57nv8g61gk4jnu2OK +bOsZasIzXSLVG2GrCbDQ+HFjWs3Fgg4JOkULfw== + + + + + + xgVcc1UZhuWRp4/8K0OAVLuQUhySUtJg7mYo78Od+WWidnIZr2XZUvPqwxOpFwRY + + + + + + + + + + + + + MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCG... (урезано для краткости) + + + + XmlElementValue1 + +``` + +--- + +### Ошибки + +| Код | Описание | Возможные значения `Error` | +| :------ | :-------------------- | :------------------------------------------------------------ | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | + +#### Пример ошибки 400 + +```xml + + + invalid_request + Authorization header is not present in request headers + +``` + +--- + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации._ + +]]> + + + +<Подключение_к_Alfa_API> + + + + + [!IMPORTANT] +> **Внимание** +> Получить и заменить `client_secret` можно двумя способами: +> +> 1. С помощью кнопки в карточке интеграции на **Портале разработчика**. +> 2. С помощью описанного ниже API-метода. + +--- + +## Эндпоинты + +| Среда | URL | +| :------------ | :----------------------------------------------------------------------- | +| **Песочница** | `POST https://sandbox.alfabank.ru/oidc/clients/{clientId}/client-secret` | +| **Пром** | `POST https://baas.alfabank.ru/oidc/clients/{clientId}/client-secret` | + +--- + +## Описание + +`client_secret` представляет собой уникальную строку символов, которая генерируется один раз и не меняется в процессе работы. Достаточно получить его **один раз** и **не менять** в дальнейшем. + +При необходимости вы можете использовать этот метод для замены `client_secret` или в случае его компрометации для получения нового. + +Если оперативная замена `client_secret` невозможна, необходимо уведомить Банк о факте компрометации по адресу: [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :--------- | :----- | :------------- | :----------------------------- | +| **Accept** | string | required | Должен быть `application/json` | + +### PATH (Путь) + +| Атрибут | Тип | Обязательность | Описание | +| :----------- | :----- | :------------- | :--------------------------------- | +| **clientId** | string | optional | Идентификатор партнёрского сервиса | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request POST 'https://baas.alfabank.ru/oidc/clients/{clientId}/client-secret' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :--------------- | :----- | :---------------------------------------- | +| **clientId** | string | Идентификатор партнёрского сервиса | +| **clientSecret** | string | Новый секретный ключ партнёрского сервиса | + +**Пример ответа:** + +```json +{ + "clientId": "0cee0683-85ae-49f2-a63d-29f97aad1911", + "clientSecret": "Qwerty1234567890Qwerty1234567890!" +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :------ | :------------- | :---------------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверный формат запроса или отсутствуют обязательные параметры. | +| **401** | Unauthorized | `invalid_token` — ошибка авторизации. | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса. | + +--- + +_Документация Alfa API_ + +]]> + + + + + + + + + ### Внимание +> Если вы ещё не являетесь клиентом Альфа-Банка, то для подключения к Alfa API вам необходимо открыть [счёт](https://alfabank.ru/sme/quick/docstariffs/), оформить [расчётно-кассовое обслуживание](https://alfabank.ru/sme/) и подключить [Альфа-Бизнес](https://alfabank.ru/corporate/rko/internet-bank/#form). + +1. **Подпишите договор** + [Подпишите договор](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding). + + Комиссия за подключение и использование не взимается. Вопросы по заключению договора можно направлять на почту [alfa_api@alfabank.ru](https://developers.alfabank.rumailto:alfa_api@alfabank.ru). + +2. **Проверьте тестовую интеграцию** + Получите тестовые учётные данные и настройте тестовую интеграцию [на Портале разработчика](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/test/test), реализуйте и протестируйте аутентификацию в Alfa ID и вызов методов Alfa API [в песочнице](https://developers.alfabank.ru/products/alfa-api/documentation/articles/sandbox/sandbox). + +3. **Подготовьтесь к промышленной интеграции** + Создайте интеграцию в проме, выпустите TLS-сертификат и `client_secret` . Подробнее [в инструкции](https://developers.alfabank.ru/products/alfa-api/documentation/articles/selfservice/articles/prod/prod). + +4. **Используйте Alfa API** + +Если вы ещё не являетесь клиентом Альфа-Банка, то для подключения к Alfa API вам необходимо открыть [счёт](https://alfabank.ru/sme/quick/docstariffs/), оформить [расчётно-кассовое обслуживание](https://alfabank.ru/sme/) и подключить [Альфа-Бизнес](https://alfabank.ru/corporate/rko/internet-bank/#form). + +--- +[← Сертификаты для Linux](https://developers.alfabank.ru/products/alfa-api/documentation/articles/specification/articles/certificate/articles/linux/linux) [← Подписание договора](https://developers.alfabank.ru/products/alfa-api/documentation/articles/connection/articles/onboarding/onboarding) + +]]> + + + **Внимание** +> Данный файл уже содержит все необходимые атрибуты и не требует внесения изменений. Все остальные параметры будут введены вручную через терминал в процессе генерации закрытого ключа и запроса на сертификат. + +> **Важно** +> Если возникает ошибка `object identifier routines:OBJ_create:oid exists`, необходимо закомментировать строку с объявлением этого OID в начале файла: `INNLE=1.2.643.100.4`. + +### 2. Сгенерируйте закрытый ключ + +1. Откройте терминал и перейдите в папку с файлом. Если это «Загрузки»: + `cd ~/Downloads` +2. Убедитесь, что файл на месте командой `ls`. +3. Сгенерируйте закрытый ключ: + `openssl genrsa -des3 -out Company.key 2048` +4. Задайте пароль для ключа (**PEM pass phrase**) и запомните его. +5. В папке появится файл `Company.key`. + +> **Рекомендация для Mac OS** +> Введите дважды пароль от вашего Mac OS, когда терминал запросит подтверждение действий. + +### 3. Сгенерируйте запрос на сертификат (CSR) + +1. Введите команду: + `openssl req -utf8 -config openssl_INNLE.cnf -key Company.key -new -sha256 -out Company.csr` +2. Атрибут `CLIENT_ID`, а также поля `An optional company name` и `A challenge password` являются опциональными (можно оставить пустыми). +3. Введите данные организации (название, ФИО, ИНН), когда терминал их запросит. + +> **Рекомендации для заполнения полей** +> Поля `OrganizationName` и `CommonName` можно заполнять транслитом или кириллицей (UTF-8). +> **ИНН:** строго 10 цифр для ЮЛ и 12 цифр для ИП (без пробелов). +> Поля `CountryName` и `INNLE` формируют имя профиля в LDAP и должны быть точными. + +### 4. Проверьте атрибуты в subject + +Проверьте созданный запрос командой: +`openssl req -config openssl_INNLE.cnf -noout -text -in Company.csr` + +**Пример корректного ответа:** + +```text +Subject: C=RU, L=Moscow, O=Company Name, CN=Ivanov Ivan Ivanovich/emailAddress=example@company.ru/INNLE=01234567890/CLIENT_ID=b95e04ed-91fe-430a-a101-894f06f3ab2a +``` + +### 5. Отправьте запрос в Банк + +Отправьте файл `Company.csr` на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +- **Тема:** «Запрос на сертификат». +- **Отправитель:** почта, указанная в Договоре. +- **Имя файла:** название организации на латинице. +- **В письме:** укажите e-mail для уведомлений об истечении срока сертификата. + +> **Важно!** Никому и никогда не передавайте файл закрытого ключа (`.key`). + +### 6. Получите сертификат + +Банк пришлет сертификат с адреса `alfa_api@alfabank.ru`. + +- **Срок действия:** 375 дней. По истечении нужно выпустить новый. + +### 7. Сборка файла контейнера pfx + +Для установки в систему соберите контейнер командой: +`openssl pkcs12 -export -out Company.pfx -inkey Company.key -in Company.cer -certfile keys\root_apica_2022.cer -certfile keys\sub_root_apica_2022.cer` + +### 8. Действия при компрометации + +Если закрытый ключ был украден или утерян, немедленно напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru) для отзыва и перевыпуска. + +--- + +## Требования к сертификату + +### Global Subject (Обязательные поля) + +| Атрибут | Значение | +| :------------------- | :--------------------------------- | +| **CountryName** | Код страны (ISO). Для России: `RU` | +| **OrganizationName** | Название организации | +| **CommonName** | ФИО представителя организации | +| **EmailAddress** | Служебный адрес для связи | + +### Variable Subject (Зависит от формы собственности) + +| Атрибут | Значение | +| :------------------------ | :------------------------------------ | +| Для ЮЛ в России | `INNLE = 1.2.643.100.4` | +| Для иностранных партнёров | `FOREIGNID = 1.3.6.1.4.1.16745.100.1` | +| Идентификатор сервиса | `CLIENT_ID = 1.3.6.1.4.1.16745.100.2` | + +--- + +## Настройка UTF-8 для кириллицы + +### Windows + +1. **Панель управления** > **Часы и регион** > **Регион**. +2. Вкладка **Дополнительно** > **Изменить язык системы**. +3. Включите чекбокс: «Бета-версия: Использовать Юникод (UTF-8) для поддержки языка во всем мире». +4. Перезагрузите ПК. + +### MacOS + +1. Откройте **Терминал**. +2. В меню: **Terminal** > **Настройки**. +3. Вкладка **Кодировки**: убедитесь, что выбрана «Unicode (UTF-8)». + +--- + +## Использование сертификата + +Использование TLS-сертификата обязательно для установки mTLS-соединения. Пример запроса через **cURL**: + +```bash +curl -X GET https://baas.alfabank.ru/api/endpoint \ + -v --cert Company.cer \ + --key Company.key \ + -H 'Accept: application/json' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Content-Type: application/json' +``` + +--- + +## Повторный выпуск сертификата + +За **1 месяц** до истечения срока вам придет уведомление. Необходимо сформировать новый запрос по инструкции выше. + +> **Внимание** +> При перевыпуске рекомендуем: +> +> - Установить защиту на удаление закрытого ключа. +> - Перезаписать старый закрытый ключ на новый. + +_В случае утери сертификата или несвоевременного обновления, ответственность за простой API возлагается на сторону клиента._ + +--- + +← [Client ID](/products/alfa-api/documentation/articles/connection/articles/clientid/clientid) | [Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) → + +]]> + + +<Портал_разработчика> + + **Внимание** +> В случае если у вас ИП, права разработчика можно назначить: +> +> - от имени самого индивидуального предпринимателя с ролью «Руководитель»; +> - от имени любого другого сотрудника ИП с ролью «Руководитель». В таком случае потребуется подтверждение назначения от владельца ИП. Подробнее в инструкции ниже. + +--- + +## Инструкция по настройке прав + +### Шаг 1. Перейдите в раздел «Пользователи и роли» + +1. На главном экране Альфа-Бизнес перейдите в настройки компании. +2. В разделе **Моя компания** выберите карточку **Пользователи и роли**. + +### Шаг 2. Создайте новую роль + +> **Внимание:** Если ранее вы уже создавали роль с правами на управление Alfa API, этот шаг можно пропустить. + +1. Нажмите **Создать роль**. +2. Укажите название роли. +3. Настройте права: новую роль рекомендуется создавать на основании прав руководителя, сбросив лишнее. +4. Нажмите **Снять все**, чтобы сбросить текущие права. +5. В разделе **Обслуживание бизнеса** выберите **Alfa API** и укажите необходимые полномочия. +6. При необходимости добавьте права из других разделов. +7. Нажмите **Создать роль** для сохранения. + +### Шаг 3. Назначьте роль разработчику + +> **Примечание:** Если пользователь еще не подключен к компании, нажмите «Подключить пользователя», заполните данные и выберите созданную роль. + +1. В разделе **Пользователи** нажмите на три точки справа от нужного сотрудника. +2. Выберите **Сменить роль**. +3. В открывшейся форме выберите созданную роль и нажмите **Сменить**. +4. Подтвердите смену роли кодом из СМС. + - _Для ИП:_ Если роль назначает не сам владелец, будет создано заявление, которое владелец должен подписать в своем личном кабинете. +5. После успешного назначения статус пользователя изменится на **Подключён**. + +--- + +## Требования к полномочиям для корректной авторизации + +Для корректной работы H2H-интеграций ключ доступа (`access_token` / `API Key`) должен получать пользователь, у которого есть полномочия на использование выбранных сервисов и продуктов. + +### Особенности способов авторизации: + +- **При использовании ACF H2H:** Авторизацию в Alfa ID должен проходить пользователь, у которого в Альфа-Бизнес настроены соответствующие полномочия на использование выбранных `scopes`. Если вы хотите использовать учетные данные разработчика, руководитель должен выдать ему соответствующие права в разделе «Пользователи и роли». +- **При использовании авторизации по API Key:** Выпускать ключ должен пользователь, имеющий права на выбранные продукты. Если у пользователя нет прав (например, на просмотр выписок), то выпущенный им `API Key` не будет работать для этого сервиса. + +**Пример:** +Если вы выдали разработчику права на _редактирование интеграций_, но не дали прав на _просмотр выписки_, то созданный им `API Key` для сервиса выписок (`transactions`) работать не будет. Ключ должен выпускать либо руководитель, либо сотрудник с полным доступом к нужным данным. + +]]> + + + **Важно** +> Выпускать `API Key` необходимо пользователю, у которого в Альфа-Бизнес настроены соответствующие полномочия на использование выбранных при выпуске ключа продуктов и сервисов. Если у пользователя отсутствуют эти полномочия, руководителю организации необходимо выдать их пользователю в Альфа-Бизнес (в разделе **Профиль** – **Пользователи и роли**) или выпустить ключ самому. + +### Шаг 1. Нажмите "Выпустить API Key" + +Нажмите **Выпустить ключ** в правой части карточки H2H-интеграции. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_1.png) + +### Шаг 2. Заполните данные для API Key + +Укажите IP-адреса, с которых будут отправляться запросы с использованием `API Key`. Отправка запросов с использованием `API Key` будет доступна только с указанных IP-адресов. + +Для одного API Key вы можете указать не более 20 IP-адресов. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_2.png) + +Укажите сервисы и продукты, доступ к которым вы хотите получать с помощью `API Key`. Вам будут доступны сервисы и продукты из набора `scopes` редактируемой H2H-интеграции, доступ к которым возможен с помощью `API Key`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_3.png) +Далее проверьте и сохраните внесённые изменения. + +### Шаг 3. Скопируйте и сохраните API Key + +После завершения выпуска `API Key` вы получите уведомление. Скопируйте его и вручную добавьте в ваши рабочие инструменты так, чтобы при отправке запросов по H2H-интеграции в запросах передавался заголовок `Authorization: ApiKey {API Key}`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/issue_4.png) + +**Срок действия:** Срок действия `API Key` неограничен, но ключ будет автоматически отозван, если с момента последнего запроса прошло более **30 дней**. + +В случае потери данных либо компрометации ключа вы можете перевыпустить его. Также вы всегда можете отозвать `API Key`, если больше не хотите использовать упрощённый способ авторизации. + +--- + +## Перевыпуск API Key + +### Шаг 1. Нажмите "Перевыпустить API Key" + +Нажмите на три точки в правом верхнем углу карточки H2H-интеграции и выберите **Перевыпустить API Key**. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_1.png) + +### Шаг 2. Отредактируйте данные для API Key + +При необходимости отредактируйте данные для `API Key`. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_2.png) +Далее проверьте внесённые изменения и нажмите «Перевыпустить». + +### Шаг 3. Скопируйте и сохраните API Key + +После перевыпуска `API Key` вы получите уведомление. Вам будет необходимо скопировать его и заменить в ваших рабочих инструментах. При перевыпуске `API Key` старый ключ, привязанный к этой интеграции, будет автоматически отозван. + +Срок действия `API Key` неограничен, но ключ будет автоматически отозван, если с момента последнего запроса прошло более 30 дней. +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/reissue_3.png) + +--- + +## Отзыв API Key + +Для отзыва ключа доступа нажмите на три точки в правом верхнем углу карточки интеграции, выберите **Отозвать API Key** и подтвердите свои действия. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/revoke_1.png) +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/api-key/files/revoke_2.png) + +В результате отзыва ключа упрощённая авторизация будет недоступна. При необходимости вы всегда можете выпустить новый `API Key`. + +]]> + + + **Внимание** +> Одновременно у вас может быть не более 5 промышленных интеграций. + +Нажмите **Создать интеграцию** в степпере или в списке интеграций, находясь в рабочей среде «Пром» (для выбора рабочей среды используйте переключатель в правом верхнем углу Портала разработчика). + +**Важно!** В случае если вы работаете в режиме группы компаний, перед созданием новой интеграции необходимо перейти в профиль пользователя и выбрать компанию, для которой вы хотите создать интеграцию. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/1.png) + +--- + +### Шаг 2. Выберите тип интеграции + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/2.png) + +--- + +### Шаг 3. Заполните основную информацию + +Укажите название интеграции (рекомендуется использовать то же название, что и у соответствующей тестовой интеграции), `redirect_uri` и тип клиентов (выбор типа клиентов доступен только для партнёрских интеграций). + +В одной интеграции вы можете указать не более 20 `redirect_uri`. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/3.png) + +--- + +### Шаг 4. Выберите сервисы и продукты + +> **Важно** +> Вам будут доступны сервисы и продукты, по которым при тестировании было выполнено не менее одного успешного запроса в песочнице. + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/4.png) + +--- + +### Шаг 5. Завершите создание промышленной интеграции + +Проверьте параметры интеграции перед её сохранением. + +Для создания интеграции потребуется некоторое время. После завершения создания промышленной интеграции вы получите уведомление: + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/5.png) + +--- + +### Шаг 6. Разблокируйте промышленную интеграцию + +После создания интеграция отображается в статусе **«Заблокирована»**. + +Для разблокирования интеграции создайте запрос на TLS-сертификат и отправьте его на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). Подробнее [на странице TLS-сертификат](/products/alfa-api/documentation/articles/connection/articles/tls/tls). + +Если вы уже выпускали сертификат, повторно выпускать его не нужно. Вместо этого необходимо сообщить о готовности к промышленной интеграции на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). После этого интеграция будет разблокирована и перейдёт в статус **«Новая»**. + +--- + +### Шаг 7. Активируйте промышленную интеграцию + +Чтобы активировать интеграцию, необходимо получить `client_secret`. Для этого нажмите на иконку в карточке интеграции: + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/6.png) + +Скопируйте `client_secret` и добавьте его в ваши рабочие инструменты. Получить его можно также с помощью [метода](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret). + +![image](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/prod/files/7.png) + +После того как вы получите `client_secret`, интеграция перейдет в статус **«Активна»** и будет доступна к использованию в промышленной среде. + +--- + +## Подключение новых продуктов к текущей промышленной интеграции + +Для подключения новых продуктов и сервисов к промышленной интеграции сначала добавьте новые `scopes` в режиме редактирования тестовой интеграции и протестируйте их в песочнице. + +После успешного тестирования отредактируйте промышленную интеграцию, добавив новые `scopes`. После этого новые продукты или сервисы будут доступны в промышленной среде. + +]]> + + + + + + **Внимание** +> Для работы с порталом вашему разработчику необходимо получить права на управление интеграциями Alfa API. Как их назначить, описано [в статье Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights). + +--- + +## Запуск первой промышленной интеграции + +1. **Войдите на Портал разработчика** + Вход осуществляется через Портал документации по кнопке **Войти** и возможен только под учётной записью сотрудника организации, подключённой к Alfa API. + ![Интерфейс входа](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/enter.png) + +2. **Проверьте тестовую интеграцию** + [Как настроить интеграцию в песочнице и протестировать её](/products/alfa-api/documentation/articles/selfservice/articles/test/test) + +3. **Создайте интеграцию в проме** + [Как создать промышленную интеграцию](/products/alfa-api/documentation/articles/selfservice/articles/prod/prod) + +4. **Выпустите промышленный TLS-сертификат** + [Как выпустить TLS-сертификат](/products/alfa-api/documentation/articles/connection/articles/tls/tls) + +5. **Используйте промышленную интеграцию в своих сервисах** + +При необходимости вы можете подключать новые продукты и сервисы к текущей интеграции и создавать новые интеграции на Портале разработчика. Также вы можете настроить упрощённую авторизацию по H2H-интеграциям с помощью [API Key](/products/alfa-api/documentation/articles/selfservice/articles/api-key/api-key). + +--- + +## Выбор рабочей среды + +На Портале разработчика предусмотрены две рабочие среды: + +- **«Песочница»** — для редактирования тестовых интеграций. +- **«Пром»** — для управления промышленными интеграциями. + +Выбор рабочей среды осуществляется с помощью переключателя в правом верхнем углу портала. + +![Выбор среды](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/mode.png) + +--- + +## Работа с группой компаний + +Пользователи с доступом к интеграциям нескольких компаний могут работать в двух режимах: группы компаний или одной выбранной компании. Это позволяет работать с интеграциями всех доступных компаний в едином окне. + +### Как переключить режим: + +1. Перейдите в профиль пользователя в правом верхнем углу Портала разработчика. + ![Профиль пользователя](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/profile.png) + +2. Выберите режим отображения компаний: + - Карточка **Все компании** — чтобы работать с интеграциями всех компаний одновременно. В этом режиме доступна единая таблица со всеми интеграциями. + - Карточка **конкретной компании** — чтобы работать только с интеграциями выбранной организации. + +![Выбор компании](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/holding.png) +![Единая таблица](/assets/developers-portal.docs.alfa-api/articles/selfservice/articles/intro/files/expanded-view.png) + +--- + +**Далее:** [Права доступа](/products/alfa-api/documentation/articles/selfservice/articles/access-rights/access-rights) | [Client secret](/products/alfa-api/documentation/articles/connection/articles/clientsecret/clientsecret) + +]]> + + +<продукты_и_сервисы> +<Номинальные_счета> + +• `true` — активен;
• `false` — деактивирован. | + +--- + +### Ошибки + +#### 400 (Bad Request) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `invalid_request` — неверные параметры запроса. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 401 (Unauthorized) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :----------------------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `invalid_token` — токен просрочен, отозван или имеет неверный формат. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 403 (Forbidden) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :--------------------------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `insufficient_scope` — недостаточно прав (несоответствие настроек scope). | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 404 (Not Found) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :-------------------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 429 (Too Many Requests) + +_Нет тела ответа._ + +#### 500 (Internal Server Error) + +| Атрибут | Тип | Описание | +| :-------------------- | :------------------ | :----------------------------------------------------------------------- | +| **error** | `string` (required) | Код ошибки. Значения:
• `internal_error` — внутренняя ошибка сервиса. | +| **error_description** | `string` (optional) | Описание ошибки. | + +#### 503 (Service Unavailable) + +_Нет тела ответа._ + +--- + +## Навигация + +- ← [Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature) +- → [Контрагенты: Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro) + +]]> +
+ +cardBankKey)); + $algo = $publicKey->withPadding(RSA::ENCRYPTION_OAEP)->withHash('sha256')->withMGFHash('sha1'); + return FunctionResult::success(base64_encode($algo->encrypt($pan))); +} +``` + +--- + +### Навигация +* ← [Введение](/products/alfa-api/documentation/articles/nominal-accounts/articles/intro/intro) +* → [Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature) + +]]> + + + **Внимание** +> Для использования сервиса у вас должен быть открыт номинальный счёт в Альфа-Банке. + +Сервис позволяет владельцам номинального счета совершать операции с денежными средствами, права на которые принадлежат другому лицу — бенефициару. + +### Кому подойдёт сервис + +- Финансовым и инвестиционным платформам; +- Маркетплейсам; +- Платформам, работающим с самозанятыми и фрилансерами; +- Для индивидуальных проектов, где требуется обеспечить безопасность проведения расчётов между участниками сделки. + +### Как это работает + +Владелец счёта добавляет сведения о бенефициарах номинального счёта и универсальных реципиентах — [раздел Контрагенты](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro), после чего может совершать операции с денежными средствами номинального счёта: + +- Идентифицировать поступаемые на номинальный счёт денежные средства — раздел [Идентификация пополнений номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/intro/intro). +- Осуществлять выплаты с номинального счёта удобным ему способом: + - [Безопасные сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro): деньги перейдут получателю только после выполнения условий сделки. + - [Прямые выплаты](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/intro/intro): выплаты без создания сделки – с биллингом (например, вывод средств бенефициара или уплата налога за исполнителя), или без биллинга (например, перевод зарегистрированному контрагенту). + +> **Важно** +> Для работы с сервисом необходимо использовать электронную подпись. Допускается использование сертификата, выпущенного с помощью [сервиса Электронная подпись](/products/alfa-api/documentation/articles/signature/articles/intro/intro), или сертификата УКЭП, выпущенного в любом аккредитованном УЦ. Процесс формирования подписи описан [в статье Как сформировать подпись](/products/alfa-api/documentation/articles/nominal-accounts/articles/signature/signature). + +### Термины и определения + +**Номинальный счёт** — это специальный банковский счёт, открытый владельцем номинального счёта для совершения операций с денежными средствами, права на которые принадлежат другому лицу – бенефициару. + +**Владелец номинального счёта (клиент банка)** — лицо, которое открыло номинальный счёт и имеет право распоряжаться денежными средствами, получать информацию о движении денежных средств и закрыть номинальный счёт. + +**Бенефициар** — лицо, которому принадлежат права на денежные средства, находящиеся на номинальном счёте. У одного номинального счёта может быть как один, так и несколько бенефициаров, но каждый из них имеет права только на свою часть денежных средств. + +**Универсальный реципиент** — лицо, которое не является бенефициаром и не имеет права на денежные средства, находящиеся на номинальном счёте. Может выступать только в качестве реципиента (получателя) в безопасных сделках и при выплатах с номинального счёта. + +--- + +### Навигация + +- ← [Получение подписанного реестра](/products/alfa-api/documentation/articles/factoring/articles/documents/v1/documents) +- → [Как зашифровать номер карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) + +--- + +_Медиа-материалы:_ + +- [Видео-презентация сервиса](/assets/developers-portal.docs.alfa-api/articles/nominal-accounts/articles/intro/files/nominal-accounts.mp4) + +]]> + + + **Внимание** +> Для подписания необходимо использовать RSA-сертификат, выпущенный с помощью [сервиса Электронная подпись](/products/alfa-api/documentation/articles/signature/signature). + +Для подписания алгоритмом RSA необходимо выполнить следующие шаги: + +#### 1. Подготовьте данные для подписи в формате JSON + +Подписываться должен весь блок данных тела запроса, исключая `digestSignatures`. + +#### 2. Выполните каноникализацию JSON-данных + +Используйте правила [RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785). + +**Пример каноникализированного JSON-сообщения:** + +```json +{ + "company": { "accountNumber": "40702810201400022055" }, + "externalId": "eb19f3ef-ca6a-4f84-a28f-c6e7b469b486", + "requisite": [ + { + "payoutId": "b766f52d-f6e6-4a47-bd71-ab332bd0d314", + "payoutRequisite": { + "byPan": { + "comment": "Курьерские услуги за период с 1.12.2020-20.12.2020", + "pan": "JSv++SDzmKNPIBrLc0G2k3W8lx6DjsHwSFptBCGvUAkq7hVe7KWeACIjjTOAeFKujHQguSIKcqmX93rakldGsTa6c5iZTEAsyhBp5dcPLti8F9x90iXNvCUgvPEXGclqBNvTCuVGaNbmAWrGbogHTn4LKmxxrmzeMIL+e51/YFdTpTnJ384xhiYzAzX4XxFY2CsgNOlyN5xCesOjgeYz+UBlW0MCcY9c8AJBh7+DwU09+zlS0GNtpti7GoETeQrjUv6aPqqu2IMGfO116/xVheUdwLNhcDCT2uvbRpmk9B7pMuLuekGhaA1odvoTghjvY1d1RWnjyO4ZrHpBMpVesg==" + }, + "payoutTotalAmount": "24.00", + "payoutType": "CARD" + }, + "selfemployed": { + "name": "Диогенович", + "patronymic": "Камень", + "surname": "Безукоризненный" + } + } + ] +} +``` + +#### 3. Сформируйте контейнер электронной подписи в формате PKCS#7 (CMS) + +Контейнер в виде структуры `ContentInfo` должен соответствовать стандарту [RFC 5652](https://www.ietf.org/rfc/rfc5652.txt). + +Для создания структуры, вычисления хэша и подписи используйте криптографические провайдеры (например, Bouncy Castle или OpenSSL). + +**Технические требования:** + +1. **Тип:** Рекомендуется присоединённая подпись. +2. **Формат:** [RFC 5652](https://www.ietf.org/rfc/rfc5652.txt) (PKCS#7/CMS). +3. **Алгоритм хэш-функции:** SHA-256 (OID 2.16.840.1.101.3.4.2.1). +4. **Алгоритм подписи:** `sha256WithRSAEncryption`. + +Структура `SignedData`: + +```asn1 +SignedData ::= SEQUENCE { + version CMSVersion, + digestAlgorithms DigestAlgorithmIdentifiers, + encapContent Info EncapsulatedContentInfo, + certificates [0] IMPLICIT CertificateSet OPTIONAL, + crls [1] IMPLICIT Revocation InfoChoices OPTIONAL, + signerInfos SignerInfos +} +``` + +Структура `SignerInfo`: + +```asn1 +SignerInfo ::= SEQUENCE { + version CMSVersion, + sid SignerIdentifier, + digestAlgorithm DigestAlgorithmIdentifier, + signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, + signatureAlgorithm SignatureAlgorithmIdentifier, + signature SignatureValue, + unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL +} +``` + +**Обязательные атрибуты в `signedAttrs`:** + +- ContentType = OID 1.2.840.113549.1.7.1 +- SigningTime = OID 1.2.840.113549.1.9.5 +- CMSAlgorithmProtection = OID 1.2.840.113549.1.9.52 (RFC 6211) +- messageDigest = OID 1.2.840.113549.1.9.4 + +_Примечание: Атрибут `unsignedAttrs` не используется._ + +#### 4. Закодируйте контейнер и передайте подпись в запросе + +Полученный PKCS#7-контейнер закодируйте в `base64` и передайте в параметре `base64Encoded` массива `digestSignatures` в теле запроса. + +--- + +### Примеры кода + +#### Пример формирования подписи на Java + +```java +@Override +public RsaSignResponse sign(RsaSignRequest request) throws Exception { + Security.addProvider(new BouncyCastleProvider()); + BouncyCastleProvider provider = (BouncyCastleProvider) Security.getProvider("BC"); + PrivateKey key = (PrivateKey) keyStore.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray()); + X509Certificate cert = (X509Certificate) keyStore.getCertificate(KEYSTORE_ALIAS); + CMSTypedData msg = new CMSProcessableByteArray(request.getDataToSign().getBytes()); + CMSSignedDataGenerator signedDataGen = new CMSSignedDataGenerator(); + X509CertificateHolder signCert = new X509CertificateHolder(cert.getEncoded()); + ContentSigner signer = new JcaContentSignerBuilder("sha256WithRSAEncryption") + .setProvider(provider) + .build(key); + signedDataGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder( + new JcaDigestCalculatorProviderBuilder().setProvider(provider).build() + ).setDirectSignature(true).build(signer, signCert)); + // добавляем сертификат в подпись + JcaCertStore certs = new JcaCertStore(Collections.singletonList(cert)); + signedDataGen.addCertificates(certs); + CMSSignedData signedData = signedDataGen.generate(msg, true); + byte[] signatureBytes = signedData.getEncoded("DER"); + MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); + byte[] hashedString = messageDigest.digest(request.getDataToSign().getBytes()); + return new RsaSignResponse() + .base64Encoded(new String(Base64.getEncoder().encode(signatureBytes))); +} +``` + +#### Пример формирования подписи на PHP + +```php +public function sign(string $data, string $password = null): string +{ + $key = file_get_contents($this->private_key); + $cert = file_get_contents($this->certificate); + $privateKey = openssl_pkey_get_private($key, $password ?: $this->private_key_password); + $certid = openssl_x509_read($cert); + $inputTmpFile = tmpfile(); + fwrite($inputTmpFile, $data); + fseek($inputTmpFile, 0); + $outputTmpFile = tmpfile(); + openssl_pkcs7_sign( + stream_get_meta_data($inputTmpFile)['uri'], + stream_get_meta_data($outputTmpFile)['uri'], + $certid, + $privateKey, + [], + PKCS7_ATTACHED + ); + fseek($outputTmpFile, 0); + $signature = fread($outputTmpFile, filesize(stream_get_meta_data($outputTmpFile)['uri'])); + $signature = trim(explode("\n\n", $signature, 2)[1]); + fclose($inputTmpFile); + fclose($outputTmpFile); + return str_replace("\n", '', $signature); +} +``` + +--- + +### Подписание алгоритмом ГОСТ с использованием сертификата УКЭП + +Для подписания может использоваться сертификат УКЭП, выпущенный любым аккредитованным УЦ. Если сертификат выдан уполномоченному лицу (не руководителю по уставу), дополнительно потребуется машиночитаемая доверенность (МЧД). + +1. Сформируйте электронную подпись с использованием криптопровайдера **КриптоПро CSP**. +2. Закодируйте полученное значение **отсоединённой** электронной подписи в формат `base64`. +3. Передайте значение в параметре `base64Encoded` массива `digestSignatures`. + +--- + +**Навигация:** + +- [Как зашифровать номер карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) +- [Получение списка номинальных счетов](/products/alfa-api/documentation/articles/nominal-accounts/articles/get-accounts/v1/get-accounts) + +]]> + +<Безопасные_сделки> + + **Важно:** Для создания сделки необходимо наличие открытого номинального счёта в Банке. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :----- | :------------- | :----------------------------------------------- | +| **accountNumber** | string | required | Номер номинального счёта | +| **expireDate** | string | required | Дата истечения сделки | +| **digestSignatures** | array | required | Электронная подпись УЛ клиента (массив объектов) | +| — **base64Encoded** | string | required | Значение электронной подписи в Base64 | +| — **signatureType** | string | required | Тип подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/deals' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accountNumber": "40817810306050000000", + "expireDate": "2032-03-02", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обязательность | Описание | +| :------------- | :------ | :------------- | :--------------------------------------------- | +| **dealId** | string | required | Идентификатор сделки | +| **status** | string | required | Статус сделки: `DRAFT` (принята для обработки) | +| **expireDate** | string | required | Дата истечения сделки | +| **isValid** | boolean | required | Флаг валидности сделки | + +**Пример JSON:** + +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "status": "DRAFT", + "expireDate": "2032-03-02", + "isValid": false +} +``` + +--- + +## Коды ошибок + +| Код | Ошибка | Описание | +| :------ | :------------------- | :------------------------------------------------------------ | +| **400** | `invalid_request` | Неверные входные параметры запроса | +| **401** | `invalid_token` | Токен просрочен, отозван или недействителен | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (ошибка в настройках scope) | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | — | Слишком много запросов (Too Many Requests) | +| **500** | `internal_error` | Внутренняя ошибка сервиса | +| **503** | — | Сервис временно недоступен | + +--- + +**Навигация:** + +- [← Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro) +- [Получение списка сделок →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deals/v1/get-deals) + +]]> + + + **Важно** +> +> - Создание этапа сделки происходит в синхронном режиме. +> - Завершение этапа сделки происходит в асинхронном режиме. + +Метод позволяет создать и завершить этап сделки. + +#### Создание этапа сделки + +После [регистрации сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal) необходимо создать этапы сделки для совершения финансовых операций. Этап сделки можно создать только для сделок в статусе `DRAFT`. + +- Если сделка предполагает совершение переводов денежных средств одновременно всем реципиентам, то достаточно создать один этап сделки. +- Если переводы денежных средств должны совершаться последовательно в несколько этапов, то следует создать соответствующее количество этапов сделки. + +#### Завершение этапа сделки + +При наступлении момента проведения расчётов по этапу сделки необходимо инициировать завершение этапа сделки. При завершении этапа сделки происходят все финансовые операции между участниками этапа сделки, и он переходит в статус `COMPLETED`. + +- Если при [добавлении реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors) в этап сделки был проставлен признак `keepOnNominalAccount = false`, то денежные средства переводятся с захолдированного кошелька депонента на основной и налоговый кошельки реципиента, холдируются там, а затем производится выплата по реквизитам реципиента с номинального счёта. +- Если был проставлен признак `keepOnNominalAccount = true`, то денежные средства переводятся на кошельки реципиента внутри системы без фактического перевода с номинального счёта. + +Завершить этап сделки можно только после [подтверждения сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). + +--- + +### Параметры запроса + +#### Headers + +| Атрибут | Описание | Тип | Обязательность | +| :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :------------- | +| **Authorization** | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | string | required | +| **Accept** | application/json | string | required | +| **Content-Type** | application/json | string | required | + +#### Body + +| Атрибут | Описание | Тип | Обязательность | +| :------------------- | :------------------------------------------------------------------- | :--------------- | :------------- | +| **dealId** | Идентификатор сделки | string | required | +| **stepId** | Идентификатор этапа сделки | string | optional | +| **action** | Действие по этапу сделки: `CREATE` (создать), `COMPLETE` (завершить) | string | required | +| **description** | Описание этапа сделки (при создании) | string | optional | +| **digestSignatures** | Массив объектов: Электронная подпись УЛ клиента | array of objects | required | +| └ **base64Encoded** | Значение электронной подписи в Base64 | string | required | +| └ **signatureType** | Тип подписи: `rsa` или `kep` | string | required | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/deals/steps' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "action": "CREATE", + "description": "Этап 1", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +#### Успешное создание (200 OK) + +| Атрибут | Описание | Тип | +| :-------------- | :------------------------- | :------ | +| **dealId** | Идентификатор сделки | string | +| **stepId** | Идентификатор этапа сделки | string | +| **stepNumber** | Порядковый номер этапа | integer | +| **description** | Описание этапа | string | + +**Пример ответа 200:** + +```json +{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepNumber": 1, + "description": "Этап 1" +} +``` + +#### Запрос принят (202 Accepted) — при завершении этапа + +| Атрибут | Описание | Тип | +| :------------ | :----------------------------------------------------------------------------------------------- | :----- | +| **status** | Статус запроса: `FAILED`, `TIMEOUT`, `PENDING`, `PAYMENT_FAILED`, `TRANSFER_FAILED`, `COMPLETED` | string | +| **requestId** | Идентификатор запроса | string | + +--- + +### Ошибки + +| Код | Описание (error / error_description) | +| :-------------------------- | :------------------------------------------------------- | +| **400 Bad Request** | `invalid_request` — неверные входные параметры | +| **401 Unauthorized** | `invalid_token` — токен просрочен или недействителен | +| **403 Forbidden** | `insufficient_scope` — нет прав на использование сервиса | +| **404 Not Found** | `unknown_endpoint` — эндпоинт не найден | +| **429 Too Many Requests** | Превышен лимит запросов (тело ответа отсутствует) | +| **500 Internal Error** | `internal_error` — внутренняя ошибка сервиса | +| **503 Service Unavailable** | Сервис недоступен (тело ответа отсутствует) | + +--- + +**Навигация:** + +- Предыдущий раздел: [Выполнение действия по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions) +- Следующий раздел: [Получение статуса запроса на завершение этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status) + +]]> + + + **Важно** +> Завершить сделку можно, только если все [этапы сделки завершены](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Описание | +| :---------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization**
_string, required_ | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
_string, required_ | application/json | +| **Content-Type**
_string, required_ | application/json | + +#### BODY + +| Атрибут | Описание | +| :----------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **dealId**
_string, required_ | Идентификатор сделки | +| **action**
_string, required_ | Действие по сделке. Возможные значения:
  • `ACCEPT` — подтвердить сделку;
  • `COMPLETE` — завершить сделку;
  • `CANCEL` — отменить сделку.
| +| **digestSignatures**
_array of objects, required_ | Электронная подпись УЛ клиента | +| **└ base64Encoded**
_string, required_ | Значение электронной подписи, закодированное в Base64 | +| **└ signatureType**
_string, required_ | Тип электронной подписи. Возможные значения:
  • `rsa` — RSA;
  • `kep` — КЭП.
| + +--- + +### Пример запроса + +```bash +curl --location --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/action' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "action": "ACCEPT", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +**204 No Content** +_Нет тела ответа_ + +**400 Bad Request** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `invalid_request` — неверные входные параметры запроса | +| **error_description**
_string, optional_ | Описание ошибки | + +**401 Unauthorized** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `invalid_token` — токен просрочен, отозван или недействителен | +| **error_description**
_string, optional_ | Описание ошибки | + +**403 Forbidden** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `insufficient_scope` — нет прав на использование сервиса (настройки scope) | +| **error_description**
_string, optional_ | Описание ошибки | + +**404 Not Found** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `unknown_endpoint` — эндпоинт не найден или неактивен | +| **error_description**
_string, optional_ | Описание ошибки | + +**429 Too Many Requests** +_Нет тела ответа_ + +**500 Internal Server Error** +| Атрибут | Описание | +| :--- | :--- | +| **error**
_string, required_ | Код ошибки: `internal_error` — внутренняя ошибка сервиса | +| **error_description**
_string, optional_ | Описание ошибки | + +**503 Service Unavailable** +_Нет тела ответа_ + +--- + +### Навигация + +- [← Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) +- [Выполнение действия по этапам сделки →](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step) + +]]> +
+ + **Важно** +> Проверка доступна только для сделок в статусе `DRAFT`. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string (required) | application/json | + +### PATH + +| Атрибут | Тип | Описание | +| :--------- | :---------------- | :------------------- | +| **dealId** | string (required) | Идентификатор сделки | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/is-valid' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 OK + +**Пример ответа:** + +```json +{ + "dealId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "isValid": true, + "description": [ + "Неверная сумма депонированных средств по этапу сделки ab9cbb96-360a-4462-a683-955cc29f7f54;" + ] +} +``` + +**Структура тела (BODY):** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **dealId** | string (required) | Идентификатор сделки | +| **isValid** | boolean (required) | Результат прохождения проверки: `true` — сделка прошла валидацию; `false` — сделка не прошла валидацию. | +| **description** | array of strings (optional) | Описание ошибок. Возвращается при неудачном прохождении валидации. | + +--- + +### Коды ошибок + +| Код | Описание | Атрибуты ответа | +| :------ | :------------------ | :-------------------------------------------------------------------------- | +| **400** | Bad Request | `error`: `invalid_request` — неверные входные параметры запроса. | +| **401** | Unauthorized | `error`: `invalid_token` — токен просрочен, отозван или недействителен. | +| **403** | Forbidden | `error`: `insufficient_scope` — недостаточно прав на использование сервиса. | +| **404** | Not Found | `error`: `unknown_endpoint` — эндпоинт не найден или неактивен. | +| **429** | Too Many Requests | Нет тела ответа. | +| **500** | Internal Error | `error`: `internal_error` — внутренняя ошибка сервиса. | +| **503** | Service Unavailable | Нет тела ответа. | + +--- + +## Навигация + +- **Назад:** [Получение информации о сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal/v1/get-deal) +- **Вперед:** [Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) + +]]> + + +• `DEPONENT` — плательщик;
• `RECIPIENT` — получатель | string | optional | + +### PATH + +| Атрибут | Описание | Тип | Обязательность | +| :--------- | :------------------------- | :----- | :------------- | +| **dealId** | Идентификатор сделки | string | required | +| **stepId** | Идентификатор этапа сделки | string | required | + +--- + +## Пример запроса + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/deals/{dealId}/steps/{stepId}/contractors?contractorId=ab9cbb96-360a-4462-a683-955cc29f7f54&role={role}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Пример ответа 200 (OK) + +```json +[ + { + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "role": "DEPONENT", + "amount": "10.00", + "purpose": "Назначение платежа", + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "keepOnNominalAccount": true, + "amounts": [ + { + "walletType": "MAIN", + "amount": "10.00" + } + ] + } +] +``` + +### BODY (Успешный ответ) + +| Атрибут | Описание | Тип | Обязательность | +| :----------------------- | :----------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :------------- | +| **beneficiaryId** | Идентификатор бенефициара или универсального реципиента | string | optional | +| **role** | Роль участника этапа сделки: `DEPONENT` (плательщик), `RECIPIENT` (получатель) | string | optional | +| **amount** | Сумма депонирования в рублях | string | optional | +| **purpose** | Назначение платежа реципиента | string | optional | +| **requisiteId** | Идентификатор платёжного реквизита реципиента | string | optional | +| **keepOnNominalAccount** | Признак вывода денег на виртуальный счёт:
• `true` — оставить в рамках номинального счёта;
• `false` — вывести по ID реквизита | boolean | optional | +| **amounts** | Массив объектов: Суммы реципиента | array of objects | optional | + +**Вложенные поля `amounts`:** + +- **walletType** (string, optional): Тип суммы (`MAIN` — основная, `TAX` — налоговая). +- **amount** (string, optional): Сумма в рублях. + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :------ | :------------------ | :------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +]]> +
+ + + + +• `EXTERNAL` — внешний (выплата с номинального счёта)
• `INTERNAL` — внутренний (выплата внутри номинального счёта) | +| **deponentId** | string | required | Идентификатор депонента | +| **recipientId** | string | required | Идентификатор реципиента | +| **amount** | string | required | Сумма в рублях | +| **status** | string | required | Статус запроса:
• `PENDING` — запрос в процессе обработки
• `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения запроса-дубля
• `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа
• `FAILED` — ошибка обработки
• `FAILED_DUPLICATE` — дубль отклонен
• `COMPLETE` — успешно завершено | + +### Пример ответа 200 + +```json +[ + { + "stepId": "f099f9dd-d5e7-4ab3-89f5-24932aa808ad", + "payoffId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "payoffType": "EXTERNAL", + "deponentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "recipientId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "100.00", + "status": "PENDING" + } +] +``` + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (основные атрибуты) | +| :------ | :------------------ | :---------------------------------------------------- | +| **400** | Bad Request | `error`: `invalid_request` — неверные параметры | +| **401** | Unauthorized | `error`: `invalid_token` — токен недействителен | +| **403** | Forbidden | `error`: `insufficient_scope` — нет прав доступа | +| **404** | Not Found | `error`: `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `error`: `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** + +- Предыдущий метод: [Проверка возможности осуществления выплат по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-is-valid/v1/deal-is-valid) +- Следующий метод: [Выполнение действия по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions) + +]]> +
+ + + + + + + + + + +• `DRAFT` — принят для последующей обработки;
• `ACTIVE` — успешно обработан;
• `BLOCKED` — ошибка в процессе обработки;
• `IN_PROGRESS` — в процессе обработки;
• `PAYMENT_FAILED` — платёж завершился неудачей;
• `CLOSED` — отменен;
• `COMPLETED` — успешно завершен | +| **isValid** | boolean (required) | Флаг валидности этапа сделки | + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :-------------------- | :----------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** + +- Предыдущий метод: [Получение статуса запроса на завершение этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status) +- Следующий метод: [Получение информации об этапе сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-step/v1/get-step) + +]]> +
+ + **Примечание** +> Депонент — это участник сделки, который выступает в качестве плательщика, реципиент — это получатель денежных средств. + +Механизм безопасных сделок используется для осуществления расчётов, при которых средства депонента временно холдируются и переходят к реципиенту только после выполнения условия сделки. При этом Банк ведет учёт (биллинг) денежных средств каждого бенефициара. + +Для работы с безопасными сделками предварительно необходимо: + +1. [Зарегистрировать контрагентов, участвующих в сделке, и их платёжные реквизиты](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro). +2. [Идентифицировать денежные средства, поступившие на номинальный счёт](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/intro/intro). + +> **Важно** +> В рамках этапа сделки выполнять платежи от бенефициара самому себе нельзя. Совершить такой перевод можно напрямую без создания сделки, используя метод [«Создание запроса на выплату с номинального счёта»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff/v1/payoff). + +--- + +### Механизм работы сделок + +1. **Зарегистрируйте сделку** + Создайте черновик сделки для дальнейшего её наполнения этапами и участниками с помощью метода [«Регистрация сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal). + +2. **Создайте этапы сделки** + Используйте метод [«Выполнение действия по этапам сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + _Внимание!_ Каждая сделка должна содержать не менее одного этапа. + +3. **Добавьте депонента в этапы сделки** + Добавьте информацию о бенефициаре (плательщике) этапа с помощью метода [«Выполнение действия по участникам этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors). + _Внимание!_ В одном этапе сделки может быть указан только один депонент (плательщик). + +4. **Добавьте реципиентов в этапы сделки** + Добавьте информацию о получателях денежных средств с помощью метода [«Выполнение действия по участникам этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors). Реципиентами могут быть бенефициары или универсальные реципиенты. + _Внимание!_ В одном этапе сделки может быть несколько реципиентов. + +5. **Проверьте возможность выплат по сформированной сделке** + Проверьте правильность наполнения с помощью метода [«Проверка возможности осуществления выплат по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-is-valid/v1/deal-is-valid). Для перехода к следующему шагу необходимо получить в ответе `isValid = true`. + +6. **Подтвердите сделку** + Подтвердите создание с помощью метода [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). Статус изменится с `DRAFT` на `ACTIVE`. + _Внимание!_ При подтверждении сделки денежные средства депонентов холдируются. + +7. **Завершите этапы сделки** + Для проведения расчётов инициируйте завершение этапа через метод [«Выполнение действия по этапам сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-step/v1/add-step). + Для контроля используйте метод [«Получение статуса запроса на завершение этапа сделки»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-request-status/v1/get-deal-request-status). При завершении этапа осуществляются выплаты. + +8. **Завершите сделку** + Используйте метод [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). Статус изменится с `ACTIVE` на `COMPLETED`. + +--- + +### Отмена сделки + +Для отмены используйте метод [«Выполнение действия по сделке»](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/deal-actions/v1/deal-actions). + +> **Важно** +> Отменить сделку можно только при условии, что ни один из её этапов не был завершён. При отмене ранее захолдированные средства депонентов будут расхолдированы. + +--- + +### Информация о сделках и выплатах по ним + +**По сделкам:** + +- [Получение информации о сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal/v1/get-deal) +- [Получение списка сделок](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deals/v1/get-deals) + +**По этапам:** + +- [Получение информации об этапе сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-step/v1/get-step) +- [Получение списка этапов сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-steps/v1/get-steps) + +**По участникам:** + +- [Получить информацию об участниках этапа сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-contractors/v1/get-contractors) + +**По переводам (платежам):** + +- [Получение списка платежей по сделке](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/get-deal-payoffs/v1/get-deal-payoffs) + +--- + +**Навигация:** + +- Назад: [Получение статуса запроса на возврат неидентифицированного пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/get-transaction-refund-request-status/v1/get-transaction-refund-request-status) +- Вперед: [Регистрация сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/add-deal/v1/add-deal) + +]]> + + + **Внимание** +> Действия с участниками сделки возможны только для сделки в статусе `DRAFT`. + +Метод позволяет добавить, изменить или удалить участника сделки. + +### Добавление участника сделки + +Каждый этап сделки должен содержать участников. При добавлении необходимо учитывать: + +- В рамках одного этапа может быть добавлен только один депонент, реципиентов может быть несколько. +- В качестве депонента может выступать только бенефициар, в качестве реципиента – бенефициар или универсальный реципиент. +- При добавлении универсального реципиента необходимо передавать его идентификатор `universalRecipientId` в параметр `beneficiaryId`. +- Если не указан идентификатор платёжного реквизита `requisiteId`, система будет использовать [ранее зарегистрированный платёжный реквизит](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites), который считается основным (`isMain = true`). + +### Изменение участника сделки + +- **Для депонента:** можно изменить сумму депонированных средств. +- **Для реципиента:** можно изменить суммы, назначение платежа, признак вывода денег на виртуальный счёт и идентификатор платёжных реквизитов. + +### Удаление участника сделки + +Позволяет удалить депонента или реципиента из этапа сделки. + +--- + +## Параметры запроса + +### Headers + +| Атрибут | Тип | Описание | +| :---------------- | :------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` (required) | application/json | +| **Content-Type** | `string` (required) | application/json | + +### Body + +| Атрибут | Тип | Описание | +| :----------------------- | :---------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | +| **action** | `string` (required) | Тип действия: `ADD_DEPONENT`, `ADD_RECIPIENT`, `DELETE_DEPONENT`, `DELETE_RECIPIENT`, `UPDATE_DEPONENT`, `UPDATE_RECIPIENT` | +| **dealId** | `string` (required) | Идентификатор сделки | +| **stepId** | `string` (required) | Идентификатор этапа сделки | +| **beneficiaryId** | `string` (required) | Идентификатор бенефициара или универсального реципиента | +| **amount** | `string` (optional) | Сумма депонирования в рублях. Доступно только для депонента | +| **purpose** | `string` (optional) | Назначение платежа реципиента. Доступно только для реципиента | +| **amounts** | `array of objects` (optional) | Суммы реципиента. Доступно только для реципиента (см. ниже) | +| **keepOnNominalAccount** | `boolean` (optional) | Признак вывода на вирт. счёт: `true` — оставить на ном. счёте; `false` — вывести на реквизиты | +| **requisiteId** | `string` (optional) | Идентификатор платёжного реквизита контрагента | +| **digestSignatures** | `array of objects` (required) | Электронная подпись УЛ Клиента (см. ниже) | + +#### Объект `amounts` (внутри Body) + +| Атрибут | Тип | Описание | +| :------------- | :------------------ | :------------------------------------------------- | +| **walletType** | `string` (optional) | Тип кошелька: `MAIN` (основной), `TAX` (налоговый) | +| **amount** | `string` (optional) | Сумма в рублях | + +#### Объект `digestSignatures` (внутри Body) + +| Атрибут | Тип | Описание | +| :---------------- | :------------------ | :------------------------------------ | +| **base64Encoded** | `string` (required) | Значение подписи в Base64 | +| **signatureType** | `string` (required) | Тип подписи: `rsa` (RSA), `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/deals/steps/contractors' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "action": "ADD_DEPONENT", + "dealId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "stepId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "10.00", + "purpose": "Назначение платежа", + "amounts": [ + { + "walletType": "MAIN", + "amount": "10.00" + } + ], + "keepOnNominalAccount": true, + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +| Код | Статус | Описание | +| :------ | :-------------------- | :-------------------------------------------- | +| **204** | No Content | Успешное выполнение. Тело ответа отсутствует. | +| **400** | Bad Request | Неверные входные параметры. | +| **401** | Unauthorized | Токен просрочен или недействителен. | +| **403** | Forbidden | Недостаточно прав (insufficient_scope). | +| **404** | Not Found | Эндпоинт не найден. | +| **429** | Too Many Requests | Слишком много запросов. | +| **500** | Internal Server Error | Внутренняя ошибка сервиса. | +| **503** | Service Unavailable | Сервис временно недоступен. | + +### Структура ошибки (400, 401, 403, 404, 500) + +| Атрибут | Тип | Описание | +| :-------------------- | :------- | :------------------------------------------------------------------------------ | +| **error** | `string` | Код ошибки (например, `invalid_request`, `invalid_token`, `insufficient_scope`) | +| **error_description** | `string` | Подробное описание ошибки | + +--- + +_Документация Alfa API_ + +]]> + + +<Выплаты> + + + + + + + + + + + **Важно** +> +> У бенефициара должен быть положительный баланс на налоговом виртуальном счёте. + +- **Вывод собственных средств бенефициара с номинального счёта.** Позволяет вывести с номинального счёта денежные средства бенефициара без создания сделки. +- **Выплата с целью уплаты налога на профессиональный доход за исполнителя.** Позволяет аккумулировать денежные средства на виртуальном налоговом счёте исполнителя и перевести денежные средства бенефициара, задепонированные с целью уплаты налога на профессиональный доход за исполнителя, на счёт в управление казначейства. +- **Возврат денежных средств с налогового виртуального кошелька.** Позволяет вернуть денежные средства бенефициара, задепонированные с целью уплаты налога на профессиональный доход за исполнителя, если оплата налога не потребовалась. + +### Механизм возврата денежных средств с налогового виртуального кошелька + +1. **Создайте запрос на возврат денежных средств с налогового виртуального кошелька** + Метод [«Создание запроса на возврат денежных средств с налогового виртуального кошелька»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund/v1/tax-refund) + +2. **Получите статус запроса на возврат налоговых денежных средств** + Метод [«Получение статуса запроса на возврат налоговых денежных средств»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) + +3. **Подтвердите или отклоните обработку запроса-дубля на возврат денежных средств с налогового виртуального кошелька** + В случае, если статус запроса на выплату уже был создан ранее, он примет статус `MANUAL_ACCEPTANCE` и его нужно будет подтвердить или отклонить. + Метод [«Подтверждение или отклонение запроса-дубля на возврат денежных средств с налогового виртуального кошелька»](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund-accept/v1/tax-refund-accept) + +]]> + + +• `true` – продолжить обработку;
• `false` – завершить (отклонить) обработку. | + +### Пример запроса (cURL) +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/payoffs/{payoffId}/accept' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accept": true +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **result** | boolean | Да | Статус обработки:
• `true` – обработка продолжена;
• `false` – обработка завершена. | + +**Пример JSON:** +```json +{ + "result": true +} +``` + +### Ошибки +| Код | Описание (error) | Описание (error_description) | +| :--- | :--- | :--- | +| **400** | `invalid_request` | Неверные входные параметры запроса. | +| **401** | `invalid_token` | Токен просрочен, отозван или имеет неверный формат. | +| **403** | `insufficient_scope` | Нет прав на использование сервиса (недостаточный scope). | +| **404** | `unknown_endpoint` | Эндпоинт не найден или неактивен. | +| **429** | — | Too Many Requests (слишком много запросов). Тело ответа отсутствует. | +| **500** | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | — | Service Unavailable (сервис недоступен). Тело ответа отсутствует. | + +--- + +## Навигация +* **Назад:** [Получение статуса запроса на выплату с номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff-request-status/v1/get-payoff-request-status) +* **Вперед:** [Получение информации о платеже](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff/v1/get-payoff) + +]]> +
+ + [!IMPORTANT] +> **Важно** +> Если идентичный запрос на выплату уже был создан ранее, то текущий запрос примет статус `MANUAL_ACCEPTANCE`. Его нужно будет подтвердить или отклонить с помощью метода [«Подтверждение или отклонение запроса-дубля на выплату»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/payoff-accept/v1/payoff-accept). + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### BODY +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **type** | string | Да | Тип платежа: `REGULAR` (обычный), `TAX` (налоговый) | +| **accountNumber** | string | Да | Номер номинального счёта | +| **deponent** | string | Нет | Идентификатор бенефициара-плательщика | +| **recipient** | object | Да | **Получатель** (см. ниже) | +| **payoutRequisite** | object | Да | **Реквизиты обычного платежа** (см. ниже) | +| **requisites** | object | Нет | **Реквизиты для налогового платежа** (см. ниже) | +| **amount** | string | Да | Сумма в рублях | +| **purpose** | string | Да | Назначение платежа | +| **tax** | object | Нет | **Параметры для налогового платежа** (см. ниже) | +| **digestSignatures** | array | Да | **Электронная подпись УЛ клиента** (см. ниже) | + +#### Вложенный объект: recipient (Получатель) +* **type** (string, обязат.): Тип получателя. Значения: `BENEFICIARY` (контрагент), `SIMPLE_PAYEE` (простой получатель). +* **name** (string, опц.): Наименование (ФИО для ФЛ, название для ЮЛ/ИП). Обязательно для `SIMPLE_PAYEE`. +* **inn** (string, опц.): ИНН (12 цифр для ФЛ/ИП, 10 для ЮЛ). Обязательно для `SIMPLE_PAYEE`. +* **kpp** (string, опц.): КПП получателя. +* **beneficiaryId** (string, опц.): Идентификатор контрагента. Обязательно для `BENEFICIARY`. + +#### Вложенный объект: payoutRequisite (Реквизиты выплаты) +* **type** (string, обязат.): Тип реквизита: `ACCOUNT`, `CARD`, `PHONE`, `BENEFICIARY_REQUISITE`. +* **requisiteId** (string, опц.): ID реквизитов контрагента. Обязательно для `BENEFICIARY_REQUISITE`. +* **pan** (string, опц.): Токен номера карты. Обязательно для `CARD`. [Инструкция по токенизации](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken). +* **phoneNumber** (string, опц.): Номер телефона. Обязательно для `PHONE`. +* **bankId** (string, опц.): ID банка получателя. Обязательно для `PHONE`. +* **accountNumber** (string, опц.): Номер счёта. Обязательно для `ACCOUNT`. +* **bik** (string, опц.): БИК банка. Обязательно для `ACCOUNT`. + +#### Вложенный объект: tax (Налоговые параметры) +* **uin** (string, обязат.): УИН (поле 22). +* **payerStatus** (string, обязат.): Статус составителя (поле 101). Примеры: `01`, `02`, `08`, `13` и др. +* **kbk** (string, обязат.): КБК (поле 104). +* **oktmo** (string, обязат.): ОКТМО (поле 105). +* **reason** (string, обязат.): Основание платежа (поле 106). Примеры: `ТП`, `ЗД`, `0`. +* **period** (string, обязат.): Налоговый период (поле 107). Формат ДД.ММ.ГГГГ или `0`. +* **docNumber** (string, обязат.): Номер документа (поле 108). +* **docDate** (string, обязат.): Дата документа (поле 109). +* **paymentKind** (string, опц.): Код типа платежа (поле 110). `ПЕ`, `ПЦ` или `0`. + +#### Вложенный объект: digestSignatures (Подписи) +* **base64Encoded** (string, обязат.): Значение подписи в Base64. +* **signatureType** (string, обязат.): Тип подписи: `rsa` или `kep`. + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/payoffs' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "type": "REGULAR", + "accountNumber": "40817810306050000000", + "deponent": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "recipient": { + "type": "BENEFICIARY", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "payoutRequisite": { + "type": "ACCOUNT", + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593" + }, + "amount": "10.00", + "purpose": "Назначение платежа", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) +```json +{ + "payoffId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +**Описание полей ответа:** +* **payoffId** (string): Уникальный идентификатор платежа. +* **status** (string): Статус запроса. Возможные значения: + * `PENDING` — в процессе обработки. + * `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения (для дублей). + * `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа. + * `FAILED` — ошибка обработки. + * `FAILED_DUPLICATE` — запрос-дубль отклонен. + * `COMPLETE` — успешно завершено. + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав доступа | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* [Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/intro/intro) +* [Получение статуса запроса на выплату](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff-request-status/v1/get-payoff-request-status) + +]]> + + +• `true` – продолжить обработку;
• `false` – завершить (отклонить) обработку. | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH \ +'https://baas.alfabank.ru/api/na/jp/v1/tax-refund/{taxRefundId}/accept?accept={accept}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +**Тело ответа (JSON):** + +```json +{ + "result": true +} +``` + +**Описание полей:** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **result** | boolean | required | Статус обработки: `true` — продолжена, `false` — завершена. | + +--- + +## Коды ошибок + +| Код | Статус | Ошибка (`error`) | Описание | +| :------ | :------------------ | :------------------- | :----------------------------------------------------- | +| **400** | Bad Request | `invalid_request` | Неверные входные параметры запроса. | +| **401** | Unauthorized | `invalid_token` | Токен просрочен, отозван или имеет неверный формат. | +| **403** | Forbidden | `insufficient_scope` | Нет прав на использование сервиса (не настроен scope). | +| **404** | Not Found | `unknown_endpoint` | Эндпоинт не найден или неактивен. | +| **429** | Too Many Requests | — | Слишком много запросов (нет тела ответа). | +| **500** | Internal Error | `internal_error` | Внутренняя ошибка сервиса. | +| **503** | Service Unavailable | — | Сервис временно недоступен (нет тела ответа). | + +--- + +## Навигация + +- **Предыдущий шаг:** [Получение статуса запроса на возврат налоговых денежных средств](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) +- **Раздел:** Номинальные счета / Выплаты + +]]> +
+ + [!IMPORTANT] +> **Важно** +> Если идентичный запрос на возврат налоговых денежных средств уже был создан ранее, то текущий запрос примет статус `MANUAL_ACCEPTANCE`. Его нужно будет подтвердить или отклонить с помощью метода [«Подтверждение или отклонение запроса-дубля на возврат налоговых денежных средств»](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/tax-refund-accept/v1/tax-refund-accept). + +## Параметры запроса + +### Заголовки (Headers) + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | `application/json` | +| **Content-Type** | string | required | `application/json` | + +### Тело запроса (Body) + +| Атрибут | Тип | Обязательность | Описание | +| :----------------------- | :------ | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **beneficiaryId** | string | required | Идентификатор бенефициара | +| **amount** | string | required | Сумма | +| **purpose** | string | required | Назначение платежа | +| **keepOnNominalAccount** | boolean | required | Признак вывода денег на основной виртуальный счёт.
• `true` — оставить в рамках номинального счёта;
• `false` — вывести по идентификатору платёжного реквизита бенефициара. | +| **requisiteId** | string | optional | Идентификатор платёжного реквизита бенефициара для вывода. Если не заполнено, используются основные реквизиты. | +| **digestSignatures** | array | required | Массив объектов электронной подписи УЛ клиента. | + +**Объект в digestSignatures:** + +- **base64Encoded** (string, required): Значение электронной подписи в Base64. +- **signatureType** (string, required): Тип подписи: `rsa` (RSA) или `kep` (КЭП). + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/tax-refund' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "beneficiaryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "amount": "10.00", + "purpose": "Назначение платежа", + "keepOnNominalAccount": false, + "requisiteId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) + +| Атрибут | Тип | Обязательность | Описание | +| :-------------- | :----- | :------------- | :--------------------------------------- | +| **taxRefundId** | string | required | Идентификатор возврата налоговых средств | +| **status** | string | required | Статус запроса (см. ниже) | + +**Возможные значения статуса:** + +- `PENDING` — запрос в процессе обработки; +- `MANUAL_ACCEPTANCE` — ожидание ручного подтверждения запроса-дубля; +- `AWAIT_EXTERNAL` — ожидание исполнения внешнего платежа; +- `FAILED` — ошибка обработки; +- `FAILED_DUPLICATE` — запрос-дубль отклонен; +- `COMPLETE` — успешно завершено. + +**Пример ответа 202:** + +```json +{ + "taxRefundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "PENDING" +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :---------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен или просрочен | +| **403** | Forbidden | `insufficient_scope` — нет прав (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Связанные методы:** + +- [Получение информации о платеже](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-payoff/v1/get-payoff) +- [Получение статуса запроса на возврат налоговых денежных средств](/products/alfa-api/documentation/articles/nominal-accounts/articles/na-payments/articles/get-tax-refund-request-status/v1/get-tax-refund-request-status) + +]]> +
+ +<Идентификация_пополнений> + + + + +`string`, required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
`string`, required | application/json | + +### PATH +| Атрибут | Описание | +| :--- | :--- | +| **id**
`string`, required | Идентификатор операции пополнения, по которой необходимо вернуть денежные средства | +| **refundId**
`string`, required | Идентификатор запроса на возврат неидентифицированного пополнения, полученный с помощью метода [«Создание запроса на возврат неидентифицированного пополнения»](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/transaction-refund/v1/transaction-refund) | + +### Пример запроса (cURL) +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/unidentified-transactions/{id}/refunds/{refundId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 200 (OK) +**BODY** +| Атрибут | Описание | +| :--- | :--- | +| **refundId**
`string`, required | Уникальный идентификатор запроса на возврат неидентифицированного пополнения | +| **status**
`string`, required | Статус запроса. Принимает возможные значения:
• `PENDING` - запрос в процессе обработки;
• `FAILED` - обработка запроса завершилась ошибкой;
• `COMPLETE` - обработка запроса завершилась успешно | +| **description**
`string`, optional | Описание причины, по которой запрос завершился ошибкой.
**Примечание:** поле доступно только при статусе запроса `FAILED` | + +#### Пример ответа 200 (OK) +```json +{ + "refundId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "FAILED", + "description": "Произошла техническая ошибка. Обратитесь в службу поддержки и сообщите код ошибки afc9b019-77ac-49ef-afb9-688b38b74cc2" +} +``` + +--- + +## Коды ошибок + +| Код | Описание | Возможные значения `error` | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (отсутствует нужный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* Предыдущий метод: [Создание запроса на возврат неидентифицированного пополнения](/products/alfa-api/documentation/articles/nominal-accounts/articles/identify-transactions/articles/transaction-refund/v1/transaction-refund) +* Следующий раздел: [Безопасные сделки: Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/intro/intro) + +]]> +
+ + + + + + + + + + + + + +<Контрагенты> + +• `PENDING` – запрос в процессе обработки;
• `FAILED` – обработка запроса завершилась ошибкой;
• `COMPLETE` – обработка запроса завершилась успешно | +| **beneficiaryId** | string | optional | Идентификатор бенефициара. Возвращается при получении статуса запроса на регистрацию бенефициара | +| **universalRecipientId** | string | optional | Идентификатор универсального реципиента. Возвращается при получении статуса запроса на регистрацию универсального реципиента | +| **description** | string | optional | Описание причины, по которой запрос завершился неудачей. Возвращается, если статус запроса равен `FAILED` | +| **resultData** | string | optional | Результаты прохождения проверки. Возвращается при получении статуса запроса на проверку бенефициара | + +--- + +## Ошибки + +| Код | Описание | Ошибка (`error`) | Детали | +| :------ | :-------------------- | :------------------- | :--------------------------------------------------- | +| **400** | Bad Request | `invalid_request` | Неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` | Токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` | Нет прав на использование сервиса (настройки scope) | +| **404** | Not Found | `unknown_endpoint` | Эндпоинт не найден или неактивен | +| **429** | Too Many Requests | — | Превышен лимит запросов (тело ответа отсутствует) | +| **500** | Internal Server Error | `internal_error` | Внутренняя ошибка сервиса | +| **503** | Service Unavailable | — | Сервис временно недоступен (тело ответа отсутствует) | + +--- + +**Навигация:** + +- [← Как это работает](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/intro/intro) +- [Создание запроса на регистрацию бенефициара →](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-beneficiary/v1/add-beneficiary) + +]]> +
+ + **Важно** +> Биллинг для универсальных реципиентов не проводится, поскольку они не являются бенефициарами и не могут иметь собственных средств на номинальном счёте. + +> **Внимание** +> Учёт денежных средств на виртуальных счетах бенефициаров будет вестись корректно только при условии, что владелец номинального счёта не использует другие каналы вывода средств (банк-клиент, бумажные поручения и др.). + +Для учёта денежных средств бенефициара — биллинга на стороне Банка — используются **виртуальные счета**. + +При регистрации бенефициара по умолчанию создается **основной виртуальный счёт**. На нём учитываются денежные средства, права на которые принадлежат бенефициару. В случае необходимости уплаты налога (при [добавлении бенефициара в качестве реципиента в этап сделки](/products/alfa-api/documentation/articles/nominal-accounts/articles/deals/articles/step-contractors/v1/step-contractors)) дополнительно создаётся **налоговый виртуальный счёт**. + +Виртуальный счёт состоит из доступных и захолдированных денежных средств: +* **Доступные денежные средства** не обременены обязательствами, их можно использовать при проведении расчётов или вывести с номинального счёта. +* **Захолдированные денежные средства** — деньги, которые уже участвуют в незавершенной сделке, их нельзя использовать для других целей или вывести. + +### Информация о балансе и операциях бенефициара +* Узнать балансы по виртуальным счетам можно с помощью метода [«Получение информации о балансе бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-balance/v1/get-balance). +* Получить список денежных операций бенефициара можно с помощью метода [«Получение списка денежных операций бенефициара»](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-transactions/v1/get-transactions). + +]]> + +<Бенефициары> + + **Важно** +> В зависимости от типа бенефициара необходимо по-разному заполнять поля запроса. + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :----- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | required | application/json | +| **Content-Type** | string | required | application/json | + +#### BODY + +| Атрибут | Тип | Обязательность | Описание | +| :------------------------ | :------ | :------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| **accountNumber** | string | required | Номер номинального счёта | +| **type** | string | required | Тип бенефициара. Возможные значения: `FL_RESIDENT`, `FL_NONRESIDENT`, `UL_RESIDENT`, `UL_NONRESIDENT`, `IP_RESIDENT`, `IP_NONRESIDENT` | +| **taxResidentUS** | boolean | required | Признак налогового резидента США | +| **foreignTaxResident** | boolean | required | Признак иностранного налогового резидента | +| **financialActivities** | boolean | optional | Признак осуществления финансовой деятельности. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **countryOfTaxResidence** | string | required | Страна налогового резидентства (ISO 3166-1 alpha-2) | +| **name** | string | optional | Наименование организации. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **registrationDate** | string | optional | Дата регистрации. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT` | +| **inn** | string | optional | ИНН. Обязательно для `UL_RESIDENT` и `UL_NONRESIDENT`. Для ФЛ/ИП указывается в `personalInformation` | +| **kpp** | string | optional | КПП. Обязательно для `UL_RESIDENT` | +| **ogrn** | string | optional | ОГРН. Обязательно для `UL_RESIDENT` | +| **personalInformation** | object | optional | Персональные данные. Заполняется только для ФЛ и ИП | +| **phoneNumber** | string | optional | Телефон | +| **email** | string | optional | Адрес электронной почты | +| **addresses** | array | required | Список адресов бенефициара | +| **documents** | array | optional | Документы (подробнее ниже) | +| **digestSignatures** | array | required | Электронная подпись УЛ клиента | + +--- + +### Детальное описание объектов + +#### personalInformation (для ФЛ и ИП) + +| Атрибут | Тип | Описание | +| :-------------- | :----- | :------------------------------------------------ | +| **inn** | string | ИНН. Обязательно для резидентов и нерезидентов ИП | +| **firstName** | string | Имя | +| **middleName** | string | Отчество (optional) | +| **lastName** | string | Фамилия | +| **citizenship** | string | Гражданство: `RU`, `BY`, `AM`, `KZ`, `KG` | +| **birthDate** | string | Дата рождения | +| **birthPlace** | string | Место рождения | +| **snils** | string | СНИЛС. Обязательно для резидентов | + +#### addresses + +| Атрибут | Тип | Описание | +| :---------- | :----- | :------------------------------------------------------------------ | +| **type** | string | `REGISTRATION_ADDRESS`, `RESIDENCE_ADDRESS`, `LEGAL_ENTITY_ADDRESS` | +| **address** | string | Текстовый адрес | +| **country** | string | Код страны (ISO 3166-1 alpha-2) | + +#### documents + +_Для резидентов обязателен `PASSPORT`. Для граждан РБ — `FOREIGN_PASSPORT`. Для остальных нерезидентов — не менее 2 документов._ + +| Атрибут | Тип | Описание | +| :--------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------ | +| **type** | string | `PASSPORT`, `FOREIGN_PASSPORT`, `RESIDENCE_PERMIT`, `STATELESS_RESIDENCE_CERTIFICATE`, `TEMPORARY_RESIDENCE_PERMIT`, `MIGRATION_CARD` | +| **serial** | string | Серия (optional) | +| **number** | string | Номер | +| **issueDate** | string | Дата выдачи | +| **expireDate** | string | Дата истечения (optional) | +| **division** | string | Код подразделения (optional) | +| **organization** | string | Орган, выдавший документ | + +--- + +### Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data-raw '{ + "accountNumber": "40817810306050000000", + "type": "FL_RESIDENT", + "taxResidentUS": false, + "foreignTaxResident": false, + "financialActivities": false, + "countryOfTaxResidence": "RU", + "name": "Акционерное общество «Ромашка»", + "registrationDate": "2025-12-18", + "inn": "0123456789", + "kpp": "0123456789", + "ogrn": "0123456789101", + "personalInformation": { + "inn": "112233445566", + "firstName": "Иван", + "middleName": "Иванoвич", + "lastName": "Иванов", + "citizenship": "RU", + "birthDate": "2000-03-02", + "birthPlace": "Г. Иркутск", + "snils": "12345678910" + }, + "phoneNumber": "79130000011", + "email": "IvanovIvan@mail.ru", + "addresses": [ + { + "type": "REGISTRATION_ADDRESS", + "address": "ул. Максима Горького 55", + "country": "RU" + } + ], + "documents": [ + { + "type": "PASSPORT", + "serial": "6953", + "number": "987435", + "issueDate": "2022-03-02", + "expireDate": "2022-03-02", + "division": "123-321", + "organization": "ОВД Иркутской области по Г. Иркутску по Октябрьскому району" + } + ], + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +#### 202 Accepted + +Запрос принят в обработку. + +| Атрибут | Тип | Описание | +| :------------ | :----- | :---------------------------------------------------------------------- | +| **requestId** | string | Идентификатор запроса | +| **status** | string | Статус: `PENDING` (в процессе), `FAILED` (ошибка), `COMPLETE` (успешно) | + +**Пример ответа 202:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +#### Коды ошибок + +- **400 Bad Request**: `invalid_request` — неверные параметры. +- **401 Unauthorized**: `invalid_token` — токен недействителен. +- **403 Forbidden**: `insufficient_scope` — нет прав доступа (недостаточный scope). +- **404 Not Found**: `unknown_endpoint` — эндпоинт не найден. +- **429 Too Many Requests**: Превышен лимит запросов. +- **500 Internal Server Error**: `internal_error` — внутренняя ошибка сервера. +- **503 Service Unavailable**: Сервис временно недоступен. + +]]> + + + **Важно** +> Первые добавленные реквизиты автоматически назначаются основными для бенефициара. + +--- + +## Параметры запроса + +### Headers + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string | Да | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | string | Да | `application/json` | +| **Content-Type** | string | Да | `application/json` | + +### Path + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :----- | :---- | :------------------------ | +| **beneficiaryId** | string | Да | Идентификатор бенефициара | + +### Body + +| Атрибут | Тип | Обяз. | Описание | +| :------------------- | :------ | :---- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **beneficiaryId** | string | Нет | Идентификатор бенефициара | +| **type** | string | Да | Тип платёжного реквизита. Возможные значения:
• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | +| **pan** | string | Нет | Токен номера карты. Поле обязательно при типе `CARD`. [Как сформировать токен](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **phoneNumber** | string | Нет | Номер телефона. Поле обязательно при типе `PHONE` | +| **bankId** | string | Нет | Идентификатор банка контрагента-получателя. Поле обязательно при типе `PHONE` | +| **accountNumber** | string | Нет | Номер счёта. Поле обязательно при типе `ACCOUNT` | +| **bik** | string | Нет | БИК банка. Поле обязательно при типе `ACCOUNT` | +| **name** | string | Нет | Тип контрагента | +| **inn** | string | Нет | ИНН организации или физического лица | +| **kpp** | string | Нет | КПП организации (только для юридических лиц) | +| **isMain** | boolean | Нет | Признак основных реквизитов. По умолчанию для первых — `true`, для следующих — `false` | +| **digestSignatures** | array | Да | Электронная подпись УЛ клиента (список объектов) | +| └ **base64Encoded** | string | Да | Значение электронной подписи в Base64 | +| └ **signatureType** | string | Да | Тип подписи: `rsa` или `kep` | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "beneficiaryId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "ООО Ромашка", + "inn": "1234567890", + "kpp": "123456789", + "isMain": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обяз. | Описание | +| :----------- | :------ | :---- | :-------------------------------------------- | +| **id** | string | Да | Идентификатор платёжного реквизита | +| **isMain** | boolean | Да | Признак основного реквизита (`true`/`false`) | +| **isActive** | boolean | Да | Признак активности реквизита (`true`/`false`) | + +**Пример ответа:** + +```json +{ + "id": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "isMain": true, + "isActive": true +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** +← [Создание запроса на проверку бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/beneficiary-scoring/v1/beneficiary-scoring) | [Получение платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-requisites/v1/get-requisites) → + +]]> +
+ + **Важно** +> Если бенефициар не пройдет проверку, он будет деактивирован в системе. + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------- | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](https://developers.alfabank.ru/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | required | `application/json` | + +### PATH + +| Атрибут | Тип | Обязательность | Описание | +| :---------------- | :------- | :------------- | :------------------------ | +| **beneficiaryId** | `string` | required | Идентификатор бенефициара | + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request POST 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/scoring' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Accept: application/json' +``` + +--- + +## Параметры ответа + +### 202 (Accepted) + +Успешное принятие запроса в обработку. + +**BODY** +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **requestId** | `string` | required | Идентификатор запроса | +| **status** | `string` | required | Статус запроса. Возможные значения:
• `PENDING` – запрос в процессе обработки;
• `FAILED` – обработка запроса завершилась ошибкой;
• `COMPLETE` – обработка запроса завершилась успешно | + +**Пример ответа:** + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :------ | :------------------ | :------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные параметры | +| **401** | Unauthorized | `invalid_token` — токен недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +## Навигация + +- **Предыдущий метод:** [Создание запроса на изменение информации о бенефициаре](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/change-beneficiary/v1/change-beneficiary) +- **Следующий метод:** [Добавление платёжных реквизитов бенефициара](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/add-requisites/v1/add-requisites) + +]]> +
+ +_string, required_ | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept**
_string, required_ | `application/json` | +| **Content-Type**
_string, required_ | `application/json` | + +### PATH + +| Атрибут | Описание | +| :---------------------------------------- | :------------------------ | +| **beneficiaryId**
_string, required_ | Идентификатор бенефициара | + +### BODY + +| Атрибут | Тип | Описание | +| :---------------------- | :--------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | +| **type** | _string, required_ | Тип контрагента. Возможные значения:
  • `FL_RESIDENT` — физ. лицо, резидент;
  • `UL_RESIDENT` — юр. лицо, резидент.
| +| **name** | _string, optional_ | Наименование организации. Поле обязательно для бенефициаров с типом `UL_RESIDENT`. | +| **registrationDate** | _string, optional_ | Дата регистрации. Поле обязательно для бенефициаров с типом `UL_RESIDENT`. | +| **personalInformation** | _object, optional_ | Обновленные персональные данные. Заполняется для бенефициаров с типом `FL_RESIDENT`. | +| ∟ **firstName** | _string, optional_ | Имя | +| ∟ **middleName** | _string, optional_ | Отчество | +| ∟ **lastName** | _string, optional_ | Фамилия | +| ∟ **birthDate** | _string, optional_ | Дата рождения | +| ∟ **birthPlace** | _string, optional_ | Место рождения | +| **phoneNumber** | _string, optional_ | Телефон | +| **email** | _string, optional_ | Адрес электронной почты | +| **addresses** | _array of objects, optional_ | Адрес бенефициара | +| ∟ **type** | _string, required_ | Тип адреса: `REGISTRATION_ADDRESS` (адрес регистрации) или `LEGAL_ENTITY_ADDRESS` (адрес юр. лица). | +| ∟ **address** | _string, required_ | Строка адреса | +| **documents** | _array of objects, optional_ | Документы. Заполняется, если `citizenship` равен `RU`. | +| ∟ **type** | _string, required_ | Тип документа: `PASSPORT`, `FOREIGN_PASSPORT`, `RESIDENCE_PERMIT`, `STATELESS_RESIDENCE_CERTIFICATE`, `TEMPORARY_RESIDENCE_PERMIT`, `MIGRATION_CARD`. | +| ∟ **serial** | _string, required_ | Серия документа | +| ∟ **number** | _string, required_ | Номер документа | +| ∟ **issueDate** | _string, required_ | Дата выдачи | +| ∟ **division** | _string, required_ | Код подразделения | +| ∟ **organization** | _string, required_ | Орган, выдавший документ | +| **isActive** | _boolean, optional_ | Статус активности бенефициара | +| **digestSignatures** | _array of objects, required_ | Электронная подпись УЛ клиента | +| ∟ **base64Encoded** | _string, required_ | Значение электронной подписи в Base64 | +| ∟ **signatureType** | _string, required_ | Тип подписи: `rsa` или `kep`. | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff --request PUT 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data-raw '{ + "type": "FL_RESIDENT", + "name": "Акционерное общество «Ромашка»", + "registrationDate": "2025-12-23", + "personalInformation": { + "firstName": "Иван", + "middleName": "Иванoвич", + "lastName": "Иванов", + "birthDate": "2000-03-02", + "birthPlace": "Г. Иркутск" + }, + "phoneNumber": "79130000011", + "email": "IvanovIvan@mail.ru", + "addresses": [ + { + "type": "REGISTRATION_ADDRESS", + "address": "ул. Максима Горького 55" + } + ], + "documents": [ + { + "type": "PASSPORT", + "serial": "6953", + "number": "987435", + "issueDate": "2022-03-02", + "division": "123-321", + "organization": "ОВД Иркутской области по Г. Иркутску по Октябрьскому району" + } + ], + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ (202 Accepted) + +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +| Атрибут | Тип | Описание | +| :------------ | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- | +| **requestId** | _string, required_ | Идентификатор запроса | +| **status** | _string, required_ | Статус запроса:
  • `PENDING` — в процессе обработки;
  • `FAILED` — ошибка обработки;
  • `COMPLETE` — успешно завершено.
| + +### Коды ошибок + +| Код | Описание | Тело ответа (основные атрибуты) | +| :------ | :------------------ | :------------------------------ | +| **400** | Bad Request | `error`: `invalid_request` | +| **401** | Unauthorized | `error`: `invalid_token` | +| **403** | Forbidden | `error`: `insufficient_scope` | +| **404** | Not Found | `error`: `unknown_endpoint` | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Error | `error`: `internal_error` | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +### Навигация + +- [← Получение информации о бенефициаре](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-beneficiary/v1/get-beneficiary) +- [Создание запроса на проверку бенефициара →](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/beneficiary-scoring/v1/beneficiary-scoring) + +]]> +
+ + **Важно** +> Необходимо, чтобы хотя бы один из активных реквизитов бенефициара был основным. + +--- + +### Параметры запроса + +#### HEADERS + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | string (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Content-Type** | string (required) | application/json | + +#### PATH + +| Атрибут | Тип | Описание | +| :---------------- | :---------------- | :--------------------------------- | +| **beneficiaryId** | string (required) | Идентификатор бенефициара | +| **requisiteId** | string (required) | Идентификатор платёжного реквизита | + +#### BODY + +| Атрибут | Тип | Описание | +| :------------------- | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **pan** | string (optional) | Токен номера карты контрагента. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **keyId** | string (optional) | Идентификатор публичного ключа для расшифровки токена номера карты | +| **phoneNumber** | string (optional) | Номер телефона контрагента | +| **bankId** | string (optional) | Идентификатор банка контрагента | +| **accountNumber** | string (optional) | Номер счёта контрагента | +| **bik** | string (optional) | БИК банка контрагента | +| **isMain** | boolean (optional) | Признак основного платёжного реквизита.
• `true` - основной;
• `false` - неосновной | +| **isActive** | boolean (optional) | Признак активности платёжного реквизита.
• `true` - активен;
• `false` - деактивирован | +| **digestSignatures** | array of objects (required) | Электронная подпись УЛ клиента | + +**Объект digestSignatures:** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **base64Encoded** | string (required) | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string (required) | Тип электронной подписи:
• `rsa` - RSA;
• `kep` - КЭП | + +--- + +### Пример запроса (cURL) + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/beneficiaries/{beneficiaryId}/requisites/{requisiteId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--data '{ + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "keyId": "1", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "isMain": true, + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +### Параметры ответа + +**204 No Content** +_Нет тела ответа_ + +**400 Bad Request** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `invalid_request` — неверные входные параметры запроса | +| **error_description** | string (optional) | Описание ошибки | + +**401 Unauthorized** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `invalid_token` — токен просрочен, отозван или недействителен | + +**403 Forbidden** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `insufficient_scope` — у пользователя нет прав на использование сервиса | + +**404 Not Found** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `unknown_endpoint` — эндпоинт не найден или неактивен | + +**429 Too Many Requests** +_Превышен лимит запросов. Нет тела ответа._ + +**500 Internal Server Error** +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **error** | string (required) | `internal_error` — внутренняя ошибка сервиса | + +**503 Service Unavailable** +_Сервис временно недоступен._ + +--- + +**Навигация:** + +- Предыдущая статья: [Получение платёжных реквизитов бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-requisites/v1/get-requisites) +- Следующая статья: [Получение информации о балансе бенефициара](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-balance/v1/get-balance) + +]]> +
+ + + + + + + + + + + + + + + + +<Универсальные_реципиенты> + + **Важно** +> Первые добавленные реквизиты автоматически назначаются основными для универсального реципиента. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **Authorization** | `string` (required) | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` (required) | application/json | +| **Content-Type** | `string` (required) | application/json | + +### PATH +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **universalRecipientId** | `string` (required) | Идентификатор универсального реципиента | + +### BODY +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **type** | `string` (required) | Тип платёжного реквизита. Возможные значения:
• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | +| **pan** | `string` (optional) | Токен номера карты. Поле обязательно при типе реквизитов `CARD`. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **phoneNumber** | `string` (optional) | Номер телефона. Поле обязательно при типе реквизитов `PHONE` | +| **bankId** | `string` (optional) | Идентификатор банка контрагента-получателя. Поле обязательно при типе реквизитов `PHONE` | +| **accountNumber** | `string` (optional) | Номер счёта. Поле обязательно при типе реквизитов `ACCOUNT` | +| **bik** | `string` (optional) | БИК банка. Поле обязательно при типе реквизитов `ACCOUNT` | +| **name** | `string` (required) | Наименование получателя. Наименование организации (для юр. лиц), либо ФИО (для физ. лиц и ИП) | +| **inn** | `string` (required) | ИНН получателя. 10 цифр — для юр.лиц, 12 цифр — для физ.лиц и ИП | +| **kpp** | `string` (optional) | КПП получателя. Поле обязательно, если тип универсального реципиента `UL_RESIDENT` | +| **isMain** | `boolean` (optional) | Признак основных платежных реквизитов. По умолчанию для первых реквизитов — `true`, для последующих — `false`. | +| **digestSignatures** | `array of objects` (required) | Электронная подпись УЛ клиента | +| **└ base64Encoded** | `string` (required) | Значение электронной подписи, закодированное в Base64 | +| **└ signatureType** | `string` (required) | Тип электронной подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса (cURL) + +```bash +curl --location --globoff 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "type": "ACCOUNT", + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "isMain": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 200 (OK) +| Атрибут | Тип | Описание | +| :--- | :--- | :--- | +| **id** | `string` (required) | Идентификатор платёжного реквизита | +| **isMain** | `boolean` (required) | Признак основного платёжного реквизита (`true` — основной, `false` — неосновной) | +| **isActive** | `boolean` (required) | Признак активности платёжного реквизита (`true` — активен, `false` — деактивирован) | + +**Пример ответа 200:** +```json +{ + "id": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "isMain": true, + "isActive": true +} +``` + +### Ошибки +| Код | Описание | Текст ошибки (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- +**Навигация:** +* [Предыдущая: Получение информации об универсальном реципиенте](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-ur/v1/get-ur) +* [Следующая: Получение платёжных реквизитов универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-requisites/v1/get-requisites) + +]]> +
+ +• `FL_RESIDENT` — физ. лицо, резидент;
• `UL_RESIDENT` — юр. лицо, резидент | +| **digestSignatures** | array of objects | Да | Электронная подпись УЛ клиента | + +**Объект digestSignatures:** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **base64Encoded** | string | Да | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string | Да | Тип электронной подписи. Возможные значения:
• `rsa` — RSA;
• `kep` — КЭП | + +--- + +## Пример запроса (cURL) + +```bash +curl --location 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--header 'Accept: application/json' \ +--data '{ + "accountNumber": "40817810306050000000", + "type": "FL_RESIDENT", + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### Успешный ответ: 202 (Accepted) + +**Пример тела ответа:** +```json +{ + "requestId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "status": "COMPLETE" +} +``` + +**Описание атрибутов:** +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **requestId** | string | Да | Идентификатор запроса | +| **status** | string | Да | Статус запроса. Принимает значения:
• `PENDING` – запрос в процессе обработки;
• `FAILED` – ошибка обработки;
• `COMPLETE` – успешно завершено | + +--- + +## Коды ошибок + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +--- + +**Навигация:** +* Предыдущая статья: [Получение списка денежных операций бенефициара](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/beneficiaries/articles/get-transactions/v1/get-transactions) +* Следующая статья: [Получение списка универсальных реципиентов номинального счёта](https://developers.alfabank.ru/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-urs/v1/get-urs) + +]]> +
+ + **Важно:** Необходимо, чтобы хотя бы один из активных реквизитов универсального реципиента был основным. + +--- + +## Параметры запроса + +### HEADERS +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **Authorization** | string | required | Bearer {access_token}, полученный по [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Content-Type** | string | required | `application/json` | + +### PATH +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **universalRecipientId** | string | required | Идентификатор универсального реципиента | +| **requisiteId** | string | required | Идентификатор платёжного реквизита | + +### BODY +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **pan** | string | optional | Токен номера карты контрагента. [Как сформировать токен номера карты](/products/alfa-api/documentation/articles/nominal-accounts/articles/cardtoken/cardtoken) | +| **keyId** | string | optional | Идентификатор публичного ключа для расшифровки токена номера карты | +| **phoneNumber** | string | optional | Номер телефона контрагента | +| **bankId** | string | optional | Идентификатор банка контрагента | +| **accountNumber** | string | optional | Номер счета контрагента | +| **bik** | string | optional | БИК банка контрагента | +| **name** | string | optional | Наименование получателя | +| **inn** | string | optional | ИНН получателя | +| **kpp** | string | optional | КПП получателя | +| **isMain** | boolean | optional | Признак основного платёжного реквизита: `true` — основной; `false` — неосновной | +| **isActive** | boolean | optional | Признак активности платёжного реквизита: `true` — активен; `false` — деактивирован | +| **digestSignatures** | array of objects | **required** | Электронная подпись УЛ клиента (см. ниже) | + +#### Струтура объекта digestSignatures: +| Атрибут | Тип | Обязательность | Описание | +| :--- | :--- | :--- | :--- | +| **base64Encoded** | string | required | Значение электронной подписи, закодированное в Base64 | +| **signatureType** | string | required | Тип электронной подписи: `rsa` (RSA) или `kep` (КЭП) | + +--- + +## Пример запроса + +```bash +curl --location --globoff --request PATCH 'https://baas.alfabank.ru/api/na/jp/v1/universal-recipients/{universalRecipientId}/requisites/{requisiteId}' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ +--data '{ + "pan": "wS7fElYo8VWeJ8KelaJ0XA==", + "keyId": "1", + "phoneNumber": "79130000011", + "bankId": "012345678910", + "accountNumber": "40817810306050000000", + "bik": "044525593", + "name": "Иванов Иван Иванович", + "inn": "112233445566", + "kpp": "123456789", + "isMain": true, + "isActive": true, + "digestSignatures": [ + { + "base64Encoded": "SEwHwYDVQQDExhDUllQVE8tUFJPIFRlc3QgQ2VudGVyIDICExIAVH4YMX0u3fEONSkAAQBUfhgwCgYIKoUDBwEBAQEEQBU0EntPGWz8EfJ5CFL2m10xeBrkAEeWDglGQDZWLKQ0ff4TyBT9X1NhG/+ETj4TcQhExy6k+WZ9w/CpF5FjyyA=", + "signatureType": "rsa" + } + ] +}' +``` + +--- + +## Параметры ответа + +### 204 No Content +Успешное выполнение запроса. Тело ответа отсутствует. + +### 400 Bad Request +| Атрибут | Описание | +| :--- | :--- | +| **error** | `invalid_request` — неверные входные параметры запроса | +| **error_description** | Описание ошибки | + +### 401 Unauthorized +| Атрибут | Описание | +| :--- | :--- | +| **error** | `invalid_token` — токен просрочен, отозван или недействителен | + +### 403 Forbidden +| Атрибут | Описание | +| :--- | :--- | +| **error** | `insufficient_scope` — нет прав (проверьте настройки scope) | + +### 404 Not Found +| Атрибут | Описание | +| :--- | :--- | +| **error** | `unknown_endpoint` — эндпоинт не найден или неактивен | + +### 429 Too Many Requests +Превышен лимит запросов. Тело ответа отсутствует. + +### 500 Internal Server Error +| Атрибут | Описание | +| :--- | :--- | +| **error** | `internal_error` — внутренняя ошибка сервиса | + +### 503 Service Unavailable +Сервис временно недоступен. Тело ответа отсутствует. + +]]> + + +• `ACCOUNT` — реквизиты счёта;
• `CARD` — номер карты (токен);
• `PHONE` — номер телефона | string | required | +| **pan** | Токен номера карты. Возвращается, если тип реквизитов `CARD` | string | optional | +| **phoneNumber** | Номер телефона. Возвращается, если тип реквизитов `PHONE` | string | optional | +| **bankId** | Идентификатор банка контрагента-получателя. Возвращается, если тип реквизитов `PHONE` | string | optional | +| **accountNumber** | Номер счёта. Возвращается, если тип реквизитов `ACCOUNT` | string | optional | +| **bik** | БИК банка. Возвращается, если тип реквизитов `ACCOUNT` | string | optional | +| **name** | Наименование получателя. Наименование организации (для ЮЛ), либо ФИО (для ФЛ и ИП) | string | required | +| **inn** | ИНН получателя (10 цифр для ЮЛ, 12 цифр для ФЛ и ИП) | string | required | +| **kpp** | КПП получателя. Возвращается, если тип универсального реципиента `UL_RESIDENT` | string | optional | +| **isMain** | Признак основного платёжного реквизита:
• `true` — основной;
• `false` — неосновной | boolean | required | +| **isActive** | Признак активности платёжного реквизита:
• `true` — активен;
• `false` — деактивирован | boolean | required | + +--- + +## Ошибки + +| Код | Описание | Тело ответа (error) | +| :--- | :--- | :--- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (недостаточный scope) | +| **404** | Not Found | `unknown_endpoint` — эндпоинт не найден или неактивен | +| **429** | Too Many Requests | Нет тела ответа | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | +| **503** | Service Unavailable | Нет тела ответа | + +]]> +
+ +• `true` — является бенефициаром;
• `false` — является универсальным реципиентом. | +| **type** | string | Да | Тип контрагента:
• `FL_RESIDENT` — физ. лицо, резидент;
• `UL_RESIDENT` — юр. лицо, резидент. | +| **isActive** | boolean | Да | Признак активности бенефициара:
• `true` — активен;
• `false` — деактивирован. | + +**Пример успешного ответа:** +```json +{ + "universalRecipientId": "ab9cbb96-360a-4462-a683-955cc29f7f54", + "accountNumber": "40817810306050000000", + "isBeneficiary": false, + "type": "FL_RESIDENT", + "isActive": true +} +``` + +--- + +## Ошибки + +### 400 — Bad Request +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `invalid_request` — неверные входные параметры запроса | +| **error_description** | string | Нет | Описание ошибки | + +### 401 — Unauthorized +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `invalid_token` — токен просрочен, отозван или неверный формат | + +### 403 — Forbidden +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `insufficient_scope` — нет прав на использование сервиса (настройки scope) | + +### 404 — Not Found +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `unknown_endpoint` — эндпоинт не найден или неактивен | + +### 429 — Too Many Requests +Нет тела ответа. Слишком много запросов. + +### 500 — Internal Server Error +| Атрибут | Тип | Обяз. | Описание | +| :--- | :--- | :--- | :--- | +| **error** | string | Да | `internal_error` — внутренняя ошибка сервиса | + +### 503 — Service Unavailable +Нет тела ответа. Сервис временно недоступен. + +--- + +## Навигация +* **Назад:** [Получение списка универсальных реципиентов номинального счёта](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/get-urs/v1/get-urs) +* **Вперед:** [Добавление платёжных реквизитов универсального реципиента](/products/alfa-api/documentation/articles/nominal-accounts/articles/counterparties/articles/universal-recipients/articles/add-requisites/v1/add-requisites) + +]]> +
+ + + + + + + +<Транспортная_подпись_и_шифрование> + + + [!IMPORTANT] +> **Внимание** +> Для шифрования и подписания сообщения необходимо предварительно загрузить сертификат, используя следующий [метод](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates). Если вы уже загружали сертификат, используя данный метод — повторно выполнять эту операцию не нужно. + +--- + +## Подпись и шифрование JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **ГОСТ Р 34.10-2012 256 бит** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса (Header):** + +- `"alg": "GOST3410_2012_256"` +- `"typ": "JWT"` +- `"cty": "JWS"` +- `"kid": "серийный номер сертификата"` +- `"b64": true` + +**Пример JWS:** + +```text +ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Зашифровать запрос + +Зашифруйте полученный на шаге два JWS-контейнер алгоритмом **ГОСТ 34.12.2015** (блочный шифр с длиной блока n = 64 бит «Магма») открытым ключом сертификата Альфа-Банка, чтобы получился **PKCS7-контейнер**, и передайте его в теле запроса. Для получения сертификата напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +**Информация об используемых стандартах ТК 26:** + +- **Алгоритм экспорта ключей KExp15** на основе симметричного блочного шифра "Магма". OID: `1.2.643.7.1.1.7.1.1` +- **Алгоритм шифрования послания "Магма"** в режиме гаммирования CTR с механизмом преобразования ключа ACPKM с вычислением имитовставки. OID: `1.2.643.7.1.1.5.1.2` + +**Пример PKCS7:** + +```text +MIITdQYJKoZIhvcNAQcDoIITZjCCE2ICAQAxggIAMIIB/AIBADCCASIwggELMRgwFgYFKoUDZAESDTEwMjc3MDAwNjczMjgxGjAYBggqhQMDgQMBARIMMDA3NzI4MTY4OTcxMQswCQYDVQQGEwJSVTEYMBYGA1UECAwPNzcg0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxKjAoBgNVBAkMIdCj0LsuINCa0LDQu9Cw0L3Rh9C10LLRgdC60LDRjyAyNzEPMA0GA1UECwwG0KPQmNCRMSEwHwYDVQQKDBjQkNCeINCQ0JvQrNCk0JAt0JHQkNCd0JoxNTAzBgNVBAMMLNCi0JXQodCiINCj0KYgMi4wINCQ0J4gItCQ0JvQrNCk0JAt0JHQkNCd0JoiAhEG04uOAGGw+alPEEvlfneqGDAXBgkqhQMHAQEHAQEwCgYIKoUDBwEBBgEEgbcwgbQEKLyfbBL4H33ZmcqKiO1B85UCDlnD2qk05vlU+4dEg34KWZLsLQv05MYwZjAfBggqhQMHAQEBATATBgcqhQMCAiQABggqhQMHAQECAgNDAARAMyQte/ak3j94OBDlA+o+CC/y4VldsMsFTA0z9zqXFR5LFLmyVop7VDJkzeXwk/BM+YIXwbWG0GnbebS3ZjuP/wQgKo8O42NksPcsAGvRWKaYYtk3RQfL9zrMZwdBtDroNjIwghE8BgkqhkiG9w0BBwEwGwYJKoUDBwEBBQECMA4EDJzOZEVIxIU3bLczkICCERA02+pMp1hYBL6KVvGmWD7NOqN0kOF5lrhPg+4Jwk2hbQiod2WFOmK0jOf3wUwF549eNMCRP5Clkz61K9b4p8CEFuodPJ65fetCUi7t1+EmSNwzBKRNzB8gNM4M12KIIJbCGpDAxyWHWe98ZgqDgCe7d/u8Lh5lqKrfrXrwHwqi+Ivdqe5ubpU37jZr1QvoWdyLocdBBoz3musKUDfuwM+tFoEydK9gK86knMXsD7ZJ3LJngy4ztGGdjBRjbF+Pg+RmR1UhCnDLEtCiJnMNN75735pXpFAgLVcUo2oexLRGh8Jw3Uh9+UthY2tRt11/e6iyrkGPmrMlcHd1poj/XC0bsIP6+kNwHMxITO2lkEKIL3B3CRZlNKMPx4dfnLt4u+cMCm+qyLqtXilxSDZp0yETzHy76ee+UdXr0kb3eGPcBidHPNpeb2EqjAE8UCuwmVfOpznl4kioEUNfCcrnPZDqHQTpNs35lQlQocyWPQOugP0OB6BC5/9kXKf5VPHcIMLeWzvor3cuac+nBaRNB4PzvwiAdBvwKp4asbvZak/MPf8I23gpdXGVtMajbUzJUlGd6Bz+G6Kz4vpUUW8IoVwXL/vPU+3N1jKbNyGvrPFrdaIoUJHu+9B92/LlmOpcxF5GssrM9MsC9e6cEl4Cq82QQn3w7AJCdHMDzgANk04cmNKDTl5DPL2YNjcmirXaVXKzO7W4Oa4PIyKAaR811tT9kKAxsJvAWODjM1wdDMSCUlK1C1DHfJdZneXY61sbbpYQoHGuC/Uo+5Z1xdLTYjjVMY5mJ/444zdWGY0Aa2BiS+vd28hx/uSlg0T93eLpJcuWvT5B5aDuBrSFPpMRCeC/VCpwfSbAAekVHGjMb1B/ABLLgbPGnTLH5RCJOUiImihn7LPhlGSop705d9TSwvItP4XO3xebqd0vpr0YvTXy8VRTzSI8UGAs+lzoGbDnqYdPYND5XR+P0vpPA3m5Yd2kBCJJoU9Z8Clzw5+Q/6X3bsa/aLmT4V3L5TZWX169gIip77EqtLUPEGEFHVUE+rmBWKcx6IBDazEsxJ4OAHkRZq7Ls6k5g3P30fwhHmXaTWGTIjRr78LHFPN15MbTthakEoAD4sMnXCmOnZtSskGyNY1U1C1Al0REql4U2dpUDebNcmTqAqwv6rPLCCA69brcXQ8ZFbyuWq39Fz4oN6OulVNNtQ6lhuTOyPCRiEIRWdW5bIROuWs1BD9M/xZOzCIJxuA/t5xusCk1BYx1D4e6cqiwpbPSAJZMDnWlNu1WT1QPEk55ihbTYGwfUmP4SUIJL8DWJvZgs7aD1ZZq5LxjZoghem8TlpwB+dlZ96geD1T6qez0DFSSL6NJkjFGkH1WYYZcTtomUrwg4yqjDlWbZOzSPAWcKwd1vkEruViOOH892FbxRUMC9EXRg4fTaRIfcgtfEO3fGAeB6fJv1pZMdNdLUOOHViuAZrhNDgBnWblqlIbl6HMmiWCoW7JryN2WXl/L1RybXO9QALAaNCmyN0zk+baqXz2ipne3CFkohucv1T++iC+SwQ+iNoxb3DfkRdBQfXPbdY75od4+g0YPN68XW3nAze1NT8kZw7Z5/bs+ZStilJTCfKx9VZaeHF+N7k4J9ll683UYp64gtxVcNx/1MQYkf6hgesh0YRtcf35HBUAilaF+1EStQHdN6tlfaB9rNwAehoHIegset/NeWBekVpo3DKLKX0qf3+J1qBr2q3nYKdApYJwgLRCtR46b865tu8puZAPLTqCk0gp0ay52kHsYxGPAeTyQsygMCQxGjcHsHJEJCEa+NvPNkBsYfick9PKe4gFJPyDiaM4yPPk6YE755Ow8OByHbSE6c4scL1CtinWIQWZJMdtN+77au7nyDwfVvIrQehnT0gWAiTZJcwsJjxpnhdhAsGkm7j1VeT4yCAAX0OvV55LVmGVVBINAJObCsybLuKA0MIPeLH4BPa/aMBGM/XigYPFVbW01PQheuWMTkGF1ru2gc2aqGKbiFY2XSbJ3u14fPUiTpLzV9bdyi15XDpVe9T4b6ioEAHzOjsTlMpwvQZOgyKw8KAyiJ1H+S8DzNlTrbzmpJyVYw8iiLceXepHMToFLnCnmey244g2dOKmMKHZT+xyMjSgiKQ8bNI7hIPhymjeQxxmYfwmfmXxSXX5bfjDuKo7Upt0GnbfKRUGKpJnm0bsK084Lxxy4XBrFQt0aNPTfAyhEylqhkctdpteIMM7gdWwQZrLhrKxJdFaU5HK0aFaIMfE4ANSC93Grpz31NgWlTKd1ZeTbnbP3vRE9wS6N+i/xI6Vmn0v928h/DPMDoiWkCx11+Ey1fAnR3inBTmVnM3j9+SIuo1tNaX2Xq4zoHXTMr5yaY9pvPPMCYrCLxX8J28bUmqR/cA5b+ot4fWyQDh0ascRk2wB2PptjcjQjxWED4vRWj/2oDNMx1lCuwPmagXAYWbDUql4LyknJUZGjePhP+7mDX6AtTtX+70jltAUlC5orD8L+IDKeRU2y+lCvdV8OfrE892XiFfOvPd6t+Pal0a0ML/Kbp7ZH642L5I73RyTFzAv06UPybwdpvEa8rssicVd3sjI5BJnJ2x3Jkl7QcSUqkk28Werjl0+/5F6C+xlJOgZ2tEX4SyiNxfVGd7dn0jsFzAzrfVqFp5tJ3f6IZ3hG4MetoQS2R3PXfETAoHz4qUE0XJ95OTxY9DCmDXtR5ce/5BC0EaJLnAexxwe+TC/kMjqUZTCKla3hhfZCG0ylGc4u8d6MtijTzkKZNiC9ww5q4T392uzltL4jp/YiHGNSvQMtgfjOeFKtNWHGMWJ/8hjYqTG5jEPWNnYwCNmxCW9Ut7jZPAnKomRiO4+cIEavgKiyiYqTBGHMDV6PZ5SvKOTATr3swLHBzSgqoczp992fWocAD9MSc+CK5oULQs2oduBWFJ5zQRuRGpjxqTjh64m1w0Ci2imHX9AY30ccpNjp/g5znWUexmioupdnZGMchy2RnFNMpflGrTGiyXgqsSSykwCLqB56pF/Qqg1v3Eq0NCWt9VKkFIi27SXfPW/jXTBs/r1EkZu2C8DqaTynjWmlo3L1yTrs1ZyXTDSiuQCzLKPEJoYHVIboZ8za1C6oVEnluh7b4rn5DLAgTgHcU2oZbu2qVePSCZwXj6tz9d74dU8DBbowTn33443YAC04VeSA8A+jsT4YKMdhCK8AkTQSAEtUjBj3Mb++T3XKEVth639oEfZ6mioIcjQ8ePu2|... (длинная строка сокращена) +``` + +### 4. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то запрос **не будет** расшифрован и подпись запроса не будет проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: ENCRYPTION` и отправить запрос, то запрос **будет** расшифрован и подпись будет проверяться. + +Банк дешифрует запрос и проверяет подпись. Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. Ошибка также будет подписана и зашифрована. Любые другие комбинации заголовков приведут к ошибке. + +--- + +## Дешифрование и проверка подписи JSON + +### 1. Дешифровать ответ + +- При заголовках `Accept: application/json` + `X-Response-ChannelSecurity: NO` ответ **не будет** подписан и зашифрован. +- При заголовках `Accept: application/jose` + `X-Response-ChannelSecurity: ENCRYPTION` ответ (включая ошибки) **будет** подписан и зашифрован. + +Полученный ответ будет в виде PKCS7-контейнера. Расшифруйте его с использованием вашего закрытого ключа. Используются те же стандарты ТК 26 (Магма, OID: `1.2.643.7.1.1.7.1.1` и `1.2.643.7.1.1.5.1.2`). + +### 2. Обработать дешифрованный ответ + +Полученный ответ будет представлен в виде компактной сериализации JWS (три части через точку): `Base64URL(Header)`, `Base64URL(Payload)`, `Base64URL(Signature)`. + +**Пример декодированного JWS:** + +| Закодированный | Раскодированный | +| :------------------------- | :------------------------------------------------------------------------------------------------------------------------------ | +| `ewogICJhbGciIDog...` | **Header:** `{"alg": "GOST3410_2012_256", "typ": "JWT", "cty": "JWS", "kid": "6d38b8e0061b0f9a94f104be57e77aa18", "b64": true}` | +| `eyJkZWJpdFR1cm5vdmVyI...` | **Payload:** `{"debitTurnover": {"amount": 0, "currencyName": "RUR"}}` | + +### 3. Проверить подпись ответа от Банка + +Используйте открытый ключ сертификата Банка для проверки подписи. Для получения сертификата напишите на [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). В поле `kid` заголовка JWS будет указан серийный номер сертификата Банка. + +### 4. Обработать ответ в формате JSON + +**Пример итогового ответа:** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +]]> + + + [!IMPORTANT] +> **Внимание** +> Для шифрования сообщения необходимо предварительно выпустить сертификат в УЦ Альфа-Банка, используя сервис [«Электронная подпись»](/products/alfa-api/documentation/articles/signature/signature). Если Вы уже выпускали сертификат — повторно выпускать не нужно. + +--- + +## Подписание и шифрование JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **RS256** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса:** + +- **Заголовок (Header):** + - `"kid"`: "серийный номер сертификата" + - `"typ"`: "JWT" + - `"alg"`: "RS256" +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS:** +`eyJhbGciOiJSUzI1NiIsImtpZCI6IjYxMDAwMzYzY2NiNzU5Y2I0NDg2MDc4NjVkMDAwMTAwMDM2M2NjIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY1Nzg4MjY4OSwiZXhwIjoxNjU3ODg2Mjg5fQ.ApKNzZ9kLMtBY3LzReSHQ7_AyDnzocGo9GTQFRmxTiRS7Lj7a55Kr4ziwZAmmwloF1063JJMOaU0lS947q6_hSct9pxzPdZ9tTmpIDGnQL-ks0oB7zz9vUSUd3G00UZXSYnuhI9BBRXvmmTaue5Y2j5zVZofLdO2dqPWCnsQULyLn_vYf8PeABhnAQ29z1Bq42uxfRFTM35cF40Tp4VBSqXDI1vxfleLusQlOZM-5Sk7O3Vy4Sf-UB03RrRGSBerZjdoMRh7dgEyoYAXS6c4MejCm2vmXKqSd7pu2V2TxOM9UTchkCS16DL-RIJtnfMjznmznU5SoMCpncvs6gRNeQ` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Зашифровать запрос + +Преобразуйте полученный JWS-контейнер алгоритмом **RS256** в соответствии с [JSON Web Encryption](https://datatracker.ietf.org/doc/html/rfc7516) и зашифруйте [открытым ключом](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/encryption/articles/json-rsa/files/cert.cer) сертификата. + +**Формат JWE:** +`BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE Authentication Tag)` + +**Структура заголовка (Protected Header):** + +- `"kid"`: "серийный номер сертификата" +- `"enc"`: "A256GCM" +- `"alg"`: "RSA-OAEP-256" + +**Пример JWE:** +`eyJlbmiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.eFcY1Fv_xN6cFDNxnMoxCjEpVTmAjhrHuB2oW1hYapBXE02qOtdKrC3W7FGVjLFlgV3... (урезано для краткости) ...ZfAY-M8w-t9l9gErE1vQFg` + +### 4. Выполнить запрос + +Необходимо передать специфические HTTP-заголовки: + +- **Без шифрования:** + `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` +- **С шифрованием:** + `Content-Type: application/jose` + `X-Request-ChannelSecurity: ENCRYPTION` + +Банк дешифрует запрос и проверяет подпись. Любые другие комбинации заголовков приведут к ошибке. + +--- + +## Дешифрование и проверка подписи JSON + +### 1. Дешифровать ответ + +Для получения зашифрованного ответа используйте заголовки: +`Accept: application/jose` + `X-Response-ChannelSecurity: ENCRYPTION` + +Необходимо дешифровать ответ с помощью вашего закрытого ключа. + +**Структура JWE (компактная сериализация):** + +1. **Protected Header** (не зашифровано) +2. **Encrypted Key** (зашифровано) +3. **Initialization Vector** (зашифровано) +4. **Ciphertext** (зашифровано) +5. **Authentication Tag** (зашифровано) + +| Закодированный JWE (пример) | Раскодированный (Protected Header) | +| :------------------------------------------------------- | :-------------------------------------------- | +| `eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0...` | `{ "enc": "A256GCM", "alg": "RSA-OAEP-256" }` | + +### 2. Обработать дешифрованный ответ + +После дешифрования JWE вы получите компактную сериализацию **JWS**, состоящую из трех частей: +`Base64URL(Header) . Base64URL(Payload) . Base64URL(Signature)` + +**Пример раскодированного JWS:** + +- **Header:** + ```json + { + "kid": "alfa-test-jwt", + "typ": "JWT", + "alg": "RS256" + } + ``` +- **Payload:** + ```json + { + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } + } + ``` + +### 3. Проверить подпись ответа от Банка + +Используйте [открытый ключ](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/encryption/articles/json-rsa/files/cert.cer) сертификата Банка для проверки подписи. Серийный номер сертификата Банка указан в поле `kid` заголовка JWS. + +### 4. Обработать ответ в формате JSON + +Итоговый результат: + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +**Ссылки для навигации:** + +- ← [Подписание TXT ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/text-gost/text-gost) +- → [Шифрование JSON ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/encryption/articles/json-gost/json-gost) + +]]> + + + + + **Внимание** +> Для получения сертификата, выпущенного через сервис [«Электронная подпись»](/products/alfa-api/documentation/articles/signature/signature), используйте метод [«Получение RSA-сертификата»](/products/alfa-api/documentation/articles/signature/articles/get-rsa/v2/get-rsa). + +--- + +## Параметры запроса + +### HEADERS + +| Атрибут | Тип | Обяз. | Описание | +| :---------------- | :------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Authorization** | `string` | required | Bearer {access_token}, полученный по [Authorization Code Flow](/products/alfa-api/documentation/articles/alfa-id/articles/acf/articles/intro/intro) / [Authorization Code Flow H2H](/products/alfa-api/documentation/articles/alfa-id/articles/acf-h2h/articles/intro/intro) | +| **Accept** | `string` | required | `application/json` | +| **Content-Type** | `string` | optional | `application/json` | + +### Пример запроса + +```bash +curl -X GET https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Обяз. | Описание | +| :------------------- | :------------- | :------- | :--------------------------------------------------------------------------------------------------------- | +| **id** | `string(uuid)` | required | ID сертификата | +| **clientId** | `string(uuid)` | required | Идентификатор партнёрского сервиса | +| **ownerName** | `string` | required | Имя владельца | +| **fingerprint** | `string` | required | Отпечаток сертификата | +| **organizationName** | `string` | optional | Наименование организации | +| **beginDateTime** | `string` | required | Дата начала действия сертификата | +| **expireDateTime** | `string` | required | Дата окончания действия сертификата | +| **status** | `string` | optional | Статус. Возможные значения:
• `ACTIVE` - активен;
• `REVOKED` - аннулирован;
• `DELETED` - удалён | +| **certificateBody** | `string` | required | Тело сертификата в виде base64-строки | +| **type** | `string` | required | Тип сертификата. Возможные значения:
• `SIGNATURE` - для подписи;
• `ENCRYPTION` - для шифрования | +| **algorithm** | `string` | required | Алгоритм сертификата | +| **serialNumber** | `string` | required | Серийный номер сертификата | + +### Пример ответа 200 (OK) + +```json +[ + { + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" + } +] +``` + +--- + +## Ошибки + +| Код | Описание | Возможные значения `error` | +| :------ | :------------- | :------------------------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры запроса | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — нет прав на использование сервиса (настройки scope) | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | + +_Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок._ + +--- + +**Навигация:** +[← Добавление нового сертификата](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates) | [Обновление сертификата →](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/patch-certificates/patch-certificates) + +]]> +
+ +• `ACTIVE` — сертификат активен;
• `REVOKED` — сертификат аннулирован | + +### Пример запроса + +```bash +curl -X PATCH https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates/{id} \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "op": "replace", + "path": "/status", + "value": "ACTIVE" + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ (200 OK) + +| Атрибут | Тип | Описание | +| :------------------- | :------------- | :-------------------------------------------------------------------------- | +| **id** | `string(uuid)` | **Required**. ID сертификата | +| **clientId** | `string(uuid)` | **Required**. Идентификатор партнёрского сервиса | +| **ownerName** | `string` | **Required**. Имя владельца | +| **fingerprint** | `string` | **Required**. Отпечаток сертификата | +| **organizationName** | `string` | **Optional**. Наименование организации | +| **beginDateTime** | `string` | **Required**. Дата начала действия сертификата | +| **expireDateTime** | `string` | **Required**. Дата окончания действия сертификата | +| **status** | `string` | **Required**. Статус: `ACTIVE` (активен), `REVOKED` (аннулирован) | +| **certificateBody** | `string` | **Required**. Тело сертификата в виде base64-строки | +| **type** | `string` | **Required**. Тип: `SIGNATURE` (для подписи), `ENCRYPTION` (для шифрования) | +| **algorithm** | `string` | **Required**. Алгоритм сертификата | +| **serialNumber** | `string` | **Required**. Серийный номер сертификата | + +#### Пример ответа 200 + +```json +{ + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBB...", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" +} +``` + +--- + +## Ошибки + +| Код | Описание | Код ошибки (`error`) | +| :------ | :------------- | :------------------------------------------------------------ | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен, отозван или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав для вызова сервиса | +| **500** | Internal Error | `internal_error` — внутренняя ошибка сервиса | + +### Примеры сообщений об ошибках + +**400 Bad Request** + +```json +{ + "error": "invalid_request", + "error_description": "Authorization header is not present in request headers" +} +``` + +**401 Unauthorized** + +```json +{ + "error": "invalid_token", + "error_description": "The access token provided is expired, revoked, malformed, or invalid for other reasons" +} +``` + +> **Важно:** Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +_Документация Alfa API_ + +]]> +
+ +• `SIGNATURE` — для подписи;
• `ENCRYPTION` — для шифрования. | +| **certificateBody** | string | required | Тело сертификата в виде base64-строки. | + +### Пример запроса + +```bash +curl -X POST https://baas.alfabank.ru/api/gd/v1/crypto-service/certificates \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -d '{ + "type": "ENCRYPTION", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=" + }' +``` + +--- + +## Параметры ответа + +### Успешный ответ: 201 Created + +| Атрибут | Тип | Обязательность | Описание | +| :------------------- | :----------- | :------------- | :---------------------------------------------------------------------- | +| **id** | string(uuid) | required | ID сертификата | +| **clientId** | string | required | Идентификатор партнёрского сервиса | +| **ownerName** | string | required | Имя владельца | +| **fingerprint** | string | required | Отпечаток сертификата | +| **organizationName** | string | optional | Наименование организации | +| **beginDateTime** | string | required | Дата начала действия сертификата | +| **expireDateTime** | string | required | Дата окончания действия сертификата | +| **status** | string | required | Статус: `ACTIVE` (активен), `REVOKED` (аннулирован), `DELETED` (удалён) | +| **certificateBody** | string | required | Тело сертификата в виде base64-строки | +| **type** | string | required | Тип сертификата (`SIGNATURE` или `ENCRYPTION`) | +| **algorithm** | string | required | Алгоритм сертификата | +| **serialNumber** | string | required | Серийный номер сертификата | + +#### Пример ответа 201 + +```json +{ + "id": "9610bc6b-f06b-41b6-bae9-6bb5b06a54dd", + "clientId": "4aa56f35-abb1-4ebe-9697-389cca4a4475", + "ownerName": "Кудрявцев Ермолай Игоревич", + "fingerprint": "333773d77ef05aa9f7b7bae8e2779418b2aedb6a", + "organizationName": "ООО 'Ромашка'", + "beginDateTime": "2023-07-28T15:11:14Z", + "expireDateTime": "2025-06-19T11:48:06Z", + "status": "ACTIVE", + "certificateBody": "MIIGATCCBLWgAwIBAgITYQADiqqgHk1/OTmNhAABAAOKqjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUAwWzELMAkGA1UEBhMCUlUxEjAQBgNVBAoTCUFsZmEtQmFuazELMAkGA1UECxMCSVQxKzApBgNVBAMTIkFsZmEtQmFuayBJc3N1aW5nIFN1Ym9yZGluYXRlIENBIDEwHhcNMjMwNzI4MTUxMTE0WhcNMjUwNjE5MTE0ODA2WjCBpzEXMBUGA1UEKgwO0JXRgNC80L7Qu9Cw0LkxGzAZBgNVBAQMEtCa0YPQtNGA0Y/QstGG0LXQsjELMAkGA1UEBhMCUlUxOzA5BgNVBAMMMtCa0YPQtNGA0Y/QstGG0LXQsiDQldGA0LzQvtC70LDQuSDQmNCz0L7RgNC10LLQuNGHMSUwIwYJKoZIhvcNAQkBFhZVc2VyNTA0QHBvY2h0b2Noa2EuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ZM3Ztf+Ro4e64R8yI4qDV/zLdJjUCx5WNBx6gcp1pJ4uhQixw+ASy4Oxu0Xp7OxmpXtvDJFi4kr6QymtzMNYqJA3GZk85p+Iobkwo5zHKyBf0tX5HwmFWjJx9CqZKp8iZAFw9nqz1uqronxyzTgULPL6eE9igVSzaVf5msV8sXXfl87guVHF+Ph18hsdng1WiCJ7Mi14ETdI9O0R5eJiPZztLIHRnXuBtB1Oa1YiiWtvkZNnpLKONwxljdTZlH7h7KfaXUwW3kX8r0p7jvO7gNhMXvOSK1JPXWevmBHrjONVlG2atWoxT2IHs2ZDz+BLxgSwLc9NIQK+qKhIMfA1wIDAQABo4ICBzCCAgMwJQYDVR0RBB4wHIILZXhhbXBsZS5jb22CDSouZXhhbXBsZS5jb20wHQYDVR0OBBYEFGbczU3B6IZhHwKsC8ODg8r4xi3nMB8GA1UdIwQYMBaAFMkXMx6bqZSglhhLbnFMgdvpc/5lMIG7BgNVHR8EgbMwgbAwga2ggaqggaeGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybIYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3JshjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDCB2wYIKwYBBQUHAQEEgc4wgcswRQYIKwYBBQUHMAKGOWh0dHBzOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNydDA8BggrBgEFBQcwAoYwaHR0cDovL3Zsa3dzNjo5MDgxL2Rpc3RycG9pbnQvQWxmYS1CYW5rX1NDQTEuY3J0MEQGCCsGAQUFBzAChjhodHRwOi8vdGVzdGptYi5hbGZhYmFuay5ydS9kaXN0cnBvaW50L0FsZmEtQmFua19TQ0ExLmNybDBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAwUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAwUAogMCAUADggEBAHTjDmxldqWkRgpT5gXKuIzyqIHjlDZMMfahcWBxqWV9XC46bcPx8gvlpzb8N+oK+X6AqDt3+vneAiGQn8iNs9ajDKtes9ulZzMUJBwzwv26DsiI3s4/0phypAcqQVHJQxvU+rdrh5FgqJcNZsuOtOaJhiO/i/3J7hoL/oxVwSk+lX4m+X5u76/Vdqk9ydKXNNnzMi12F4FvD+igTrezzLjPHQRx5vLY0cWwLEdBxLJmBwd1u7EBT3j+v9Pyh0pTzXsJC0BY1BIt6VOh6QGKGTKT3cBB6zbIOrY7UTOkYdCqtyB9vhayAyti3aO37PANUQ7dUwUEZyf64/D4/HRlhqI=", + "type": "ENCRYPTION", + "algorithm": "RS256", + "serialNumber": "2163173489423972678179275487230070851350268586" +} +``` + +--- + +## Ошибки + +| Код | Описание | Код ошибки (в теле) | +| :------ | :-------------------- | :--------------------------------------------------------- | +| **400** | Bad Request | `invalid_request` — неверные входные параметры | +| **401** | Unauthorized | `invalid_token` — токен просрочен или недействителен | +| **403** | Forbidden | `insufficient_scope` — недостаточно прав (настройки scope) | +| **500** | Internal Server Error | `internal_error` — внутренняя ошибка сервиса | + +> Значения параметров ошибок могут изменяться. Рекомендуем предусмотреть стандартную обработку ошибок, не описанных в текущей версии документации. + +--- + +### Навигация + +← [Для чего это нужно](/products/alfa-api/documentation/articles/signature-encryption/articles/intro/intro) | [Получение сертификатов](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/get-certificates/get-certificates) → + +]]> +
+
+ + + + + + **Внимание** +> Для подписания сообщения необходимо предварительно загрузить сертификат, используя следующий [метод](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/post-certificates/post-certificates). Если Вы уже загружали сертификат, используя данный метод — повторно выполнять эту операцию не нужно. + +## Подписание JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения:** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом ГОСТ Р 34.10-2012 256 бит в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата. + +**Формат JWS:** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса:** + +- **Заголовок (Header)** + - `"alg": "GOST3410_2012_256"` + - `"typ": "JWT"` + - `"cty": "JWS"` + - `"kid": "серийный номер сертификата"` + - `"b64": true` +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS:** + +```text +ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то подпись запроса не будет проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: SIGNATURE` и отправить запрос, то подпись запроса будет проверяться. +- Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. + +Любые другие комбинации заголовков `Content-Type + X-Request-ChannelSecurity` приведут к ошибке. + +--- + +## Проверка подписи JSON + +### 1. Получить ответ + +- Если добавить заголовки `Accept: application/json` + `X-Response-ChannelSecurity: NO`, то ответ не будет подписан. +- Если добавить заголовки `Accept: application/jose` + `X-Response-ChannelSecurity: SIGNATURE`, то полученный ответ (в том числе ошибки) будет подписан и представлен в виде компактной сериализации. + +Любые другие комбинации заголовков `Accept + X-Response-ChannelSecurity` приведут к ошибке. + +**Декодирование компактной сериализации JWS** +JWS формируется из трёх составляющих и представляет структуру вида: + +1. Base64URL(Header); +2. Base64URL(Payload); +3. Base64URL(Signature). + +**Пример JWS:** + +| Закодированный | Раскодированный | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ewogICJhbGciIDogIkdPU1QzNDEwXzIwMTJfMjU2IiwKICAidHlwIiA6ICJKV1QiLAogICJjdHkiIDogIkpXUyIsCiAgImtpZCIgOiAiNmQzOGI4ZTAwNjFiMGY5YTk0ZjEwNGJlNTdlNzdhYTE4IiwKICAiYjY0IiA6IHRydWUKfQ.eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.ByCkNenTTtZQrnZplNOo9WyqPTxb6vFq0iExNHpuPCV6LUeXDFTe8tNBZCy1WvpdUCQBrKK447s3NJCC5hNLhA` | **header** `json { "alg": "GOST3410_2012_256", "typ": "JWT", "cty": "JWS", "kid": "6d38b8e0061b0f9a94f104be57e77aa18", "b64": true } ` **payload** `json { "debitTurnover": { "amount": 0, "currencyName": "RUR" } } ` **verify signature** `text HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), ) ` | + +### 2. Проверить подпись ответа от Банка + +Используйте открытый ключ сертификата Банка для проверки подписи. Для получения сертификата напишите на почту [alfa_api@alfabank.ru](mailto:alfa_api@alfabank.ru). + +Проверьте подпись в соответствии с данными, указанными в Заголовке (Header). В поле `kid` заголовка JWS будет записан серийный номер сертификата Банка. + +### 3. Обработать ответ в формате JSON + +**Пример ответа:** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +[← Подписание JSON RSA-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-rsa/json-rsa) | [Подписание XML RSA-сертификатом →](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/xml-rsa/xml-rsa) + +]]> + + + **Внимание** +> Для подписания сообщения необходимо предварительно выпустить сертификат в УЦ Альфа-Банка, используя сервис ["Электронная подпись"](/products/alfa-api/documentation/articles/signature/signature). Если Вы уже выпускали сертификат - повторно выпускать не нужно. + +--- + +## Подписание JSON + +### 1. Подготовить сообщение в формате JSON + +**Пример сообщения** + +```json +{ + "sub": "1234567890", + "name": "John Doe", + "admin": true, + "iat": 1657882689, + "exp": 1657886289 +} +``` + +### 2. Подписать запрос + +Тело запроса сформировать алгоритмом **RS256** в виде компактной сериализации в соответствии с [JSON Web Signature](https://www.rfc-editor.org/rfc/rfc7515#section-3.1) и подписать тело запроса закрытым ключом сертификата, выпущенным в сервисе "Электронная подпись". + +**Формат JWS** +`BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature)` + +**Структура тела запроса** + +- **Заголовок (Header)** + - `"kid"`: "серийный номер сертификата" + - `"typ"`: "JWT" + - `"alg"`: "RS256" +- **JSON-документ (Payload)** +- **Подпись запроса (Signature)** + +**Пример JWS** + +```text +eyJhbGciOiJSUzI1NiIsImtpZCI6IjYxMDAwMzYzY2NiNzU5Y2I0NDg2MDc4NjVkMDAwMTAwMDM2M2NjIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTY1Nzg4MjY4OSwiZXhwIjoxNjU3ODg2Mjg5fQ.ApKNzZ9kLMtBY3LzReSHQ7_AyDnzocGo9GTQFRmxTiRS7Lj7a55Kr4ziwZAmmwloF1063JJMOaU0lS947q6_hSct9pxzPdZ9tTmpIDGnQL-ks0oB7zz9vUSUd3G00UZXSYnuhI9BBRXvmmTaue5Y2j5zVZofLdO2dqPWCnsQULyLn_vYf8PeABhnAQ29z1Bq42uxfRFTM35cF40Tp4VBSqXDI1vxfleLusQlOZM-5Sk7O3Vy4Sf-UB03RrRGSBerZjdoMRh7dgEyoYAXS6c4MejCm2vmXKqSd7pu2V2TxOM9UTchkCS16DL-RIJtnfMjznmznU5SoMCpncvs6gRNeQ +``` + +Для тестовой проверки можно использовать [https://token.dev/](https://token.dev/). + +### 3. Выполнить запрос + +- Если добавить заголовки `Content-Type: application/json` + `X-Request-ChannelSecurity: NO` и отправить запрос, то подпись запроса **не будет** проверяться. +- Если добавить заголовки `Content-Type: application/jose` + `X-Request-ChannelSecurity: SIGNATURE` и отправить запрос, то подпись запроса **будет** проверяться. + +Если подпись валидна — запрос обрабатывается, если невалидна — Банк определяет запрос как неподлинный и возвращает ошибку. Любые другие комбинации заголовков `Content-Type + X-Request-ChannelSecurity` приведут к ошибке. + +--- + +## Проверка подписи JSON + +### 1. Получить ответ + +- Если добавить заголовки `Accept: application/json` + `X-Response-ChannelSecurity: NO`, то ответ **не будет** подписан. +- Если добавить заголовки `Accept: application/jose` + `X-Response-ChannelSecurity: SIGNATURE`, то полученный ответ (в том числе ошибки) **будет подписан** и представлен в виде компактной сериализации. + +Любые другие комбинации заголовков `Accept + X-Response-ChannelSecurity` приведут к ошибке. + +**Декодирование компактной сериализации JWS** +JWS формируется из трёх составляющих: + +- Base64URL(Header); +- Base64URL(Payload); +- Base64URL(Signature). + +**Пример JWS** + +| ЗАКОДИРОВАННЫЙ | РАСКОДИРОВАННЫЙ | +| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `eyJraWQiOiJhbGZhLXRlc3Qtand0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.`
`eyJkZWJpdFR1cm5vdmVyIjp7ImFtb3VudCI6MCwiY3VycmVuY3lOYW1lIjoiUlVSIn19.`
`Y1NqCkRjjtJ2GrVsW-a627g6ObfpEaKw-H92QVgVWqL9i7d1SHyaXVghF4ZNZAlrFasKySnKYZf2Ik8zVIlLN7hqeYxoeTdE2OLbiQdvPrD-JnI2Qzh0K32vcImwgGcpq2lt_QKx1f_YmaSRhH9O3xZePVcmFGCqhl_0prQSwcR4g-yuhidvspaF48QlUHcEaZ65Cr8hdyc6g9HPZDy7ipU-zCAZGgK0enxfWn4Osyqch8RRDIsfLG7OJ4wbYwYB22LYO5UaxX8Zy_R2jSnKlNghxQwSqJGxizMFhFhdCrATGTo-ysI-7OtfremD8YNj7z_iYciyYbtAgV0ZodEvMA` | **header**
`{"kid": "alfa-test-jwt", "typ": "JWT", "alg": "RS256"}`

**payload**
`{"debitTurnover": {"amount": 0, "currencyName": "RUR"}}`

**verify signature**
`RSASHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload))` | + +### 2. Проверить подпись ответа от Банка + +Используйте [открытый ключ](/assets/developers-portal.docs.alfa-api/articles/signature-encryption/articles/signature/articles/json-rsa/files/cert.cer) сертификата для проверки подписи. + +Проверьте подпись в соответствии с данными, указанными в Заголовке (Header). В поле `kid` заголовка JWS будет записан серийный номер сертификата Банка. + +### 3. Обработать ответ в формате JSON + +**Пример ответа** + +```json +{ + "debitTurnover": { + "amount": 0, + "currencyName": "RUR" + } +} +``` + +--- + +**← [Обновление сертификата](/products/alfa-api/documentation/articles/signature-encryption/articles/managing-certificates/articles/patch-certificates/patch-certificates)** | **[Подписание JSON ГОСТ-сертификатом](/products/alfa-api/documentation/articles/signature-encryption/articles/signature/articles/json-gost/json-gost) →** + +]]> +
+
+ +
diff --git a/_docs/xml/alfa_payout_docs.xml b/_docs/xml/alfa_payout_docs.xml new file mode 100644 index 0000000..e160e2e --- /dev/null +++ b/_docs/xml/alfa_payout_docs.xml @@ -0,0 +1,9787 @@ + + +<_0_full_md> + **Тема:** Регистрация сертификата на [тестовом/промышленном] стенде СБП C2B +> +> **Тело:** +> Просим зарегистрировать сертификат для работы с СБП C2B. +> * **Тип регистрации:** Впервые / Повторно (взамен истёкшего alias...) +> * **Организация:** [Название] +> * **ИНН:** [Номер] +> * **Вложение:** client.crt (в архиве без пароля) + +### 2.3. Что вы получите от банка +После регистрации банк предоставит: +1. **Alias** — имя вашего сертификата (передается в заголовке `key-name`). +2. **Клиентский сертификат RSA/TLS** — для поднятия MTLS-соединения. +3. **Корневые сертификаты банка** — для проверки серверного сертификата. +4. **TermNo** — тестовый номер терминала. +5. **Эндпойнт** — для промышленной среды. + +--- + +## 3. Техническая реализация запроса + +### 3.1. Формирование заголовков (Headers) +При каждом запросе необходимо передавать следующие заголовки: + +| Заголовок | Значение | +| :--- | :--- | +| `Content-Type` | `application/x-www-form-urlencoded` | +| `Authorization` | Base64-строка зашифрованного хеша (см. ниже) | +| `key-name` | Ваш **Alias**, полученный от банка | + +### 3.2. Подпись сообщения (Security) +Процесс формирования заголовка `Authorization`: + +1. **Подготовка данных:** Сформируйте JSON-тело запроса. Исключите все пробелы, табуляции и переносы строк между ключами и значениями. +2. **Вычисление хеша и подпись:** + ```bash + # Расчет SHA256 и подпись приватным ключом + openssl dgst -sha256 -sign client.key -out signature.txt block.txt + ``` +3. **Кодирование в Base64:** + ```bash + # Получение строки для заголовка Authorization + base64 signature.txt > signature64.txt + ``` + +--- + +## 4. Тестирование + +### 4.1. Эндпойнт тестовой среды +`https://217.12.103.132:2443/fsCryptoProxy` + +### 4.2. Пример запроса (GetQRCd) +**Body:** +```json +{ + "command":"GetQRCd", + "TermNo":"90080567", + "qrcType":"01", + "amount":"100", + "currency":"RUB", + "paymentPurpose":"Назначение платежа" +} +``` + +> **Важно по полю `paymentPurpose`:** +> * Макс. длина: 140 символов. +> * Допустимы: Латиница, Кириллица (кроме Ё/ё), цифры и спецсимволы. +> * Перенос строки передается как `\\n` (двойной слэш для JSON). + +### 4.3. Как провести тестовую оплату +1. Сгенерируйте QR-код через API. +2. Откройте на смартфоне: [testpay.alfabank.ru/sbp-page](https://testpay.alfabank.ru/sbp-page). +3. Нажмите **"Сканировать QR"** и наведите камеру на код. +4. Нажмите **"Произвести оплату"**. Выбор банка не требуется. + +--- + +## 5. Статусы и уведомления + +### Получение статуса платежа +Существует два способа: +1. **Запрос `GetQRCstatus`:** Опрос шлюза клиентом. +2. **Callback-уведомления:** ПШ банка отправляет POST-запрос на ваш сервер. + +### Настройка Callback +* Сервер ТСП должен быть публичным (HTTPS, порт 443). +* IP-адреса банка для белого списка: `217.12.97.124`, `217.12.101.32`. +* Для включения отправьте URL обработчика на [acquiring@alfabank.ru](mailto:acquiring@alfabank.ru). + +### Лимиты на тестовой среде (`GetQRCstatus`) +* **Лимит ТСП:** не более 4 запросов в минуту. +* **Общий лимит НСПК:** 60 запросов в минуту на весь банк. +* При превышении возвращается ошибка `429 Too Many Requests`. + +--- + +## 6. Переход в промышленную среду (Production) + +Для выхода в "бой" необходимо: +1. Заключить договор по СБП с Альфа-Банком. +2. Сгенерировать новую ключевую пару для промышленной среды. +3. Направить письмо на регистрацию (аналогично тестовой, но с пометкой "промышленный стенд"). +4. Срок предоставления доступов — **до 3 рабочих дней**. + +## Общие положения + +### Техническая документация СБП: Общие положения + +Данный документ описывает принципы взаимодействия, идентификации и основные бизнес-сценарии при работе с Системой Быстрых Платежей (СБП) через хост Альфа-Банка. + +--- + +## 1. Каналы взаимодействия и безопасность + +Взаимодействие осуществляется по протоколу **HTTP(S)** с обязательной двусторонней аутентификацией. + +### Требования к сертификатам +* **Тип:** Клиентские сертификаты RSA/TLS. +* **Управление:** Порядок выпуска и установки определяется Удостоверяющим Центром Заказчика. +* **Именование (Alias):** На прокси-сервере Заказчика должны соблюдаться строгие правила именования: + +| Параметр | Требование к имени (алиасу) | +| :--- | :--- | +| **Обычный запрос** | Должно соответствовать коду терминала и реквизиту заголовка `key-name`. | +| **Проверка соединения** | Должно быть равно параметру `TermNo` в теле запроса и заголовку `key-name`. | + +--- + +## 2. Идентификация Виртуального терминала + +Для работы в системе каждому терминалу присваивается уникальный идентификатор — **TermNo**. + +* **Назначение:** Определение конкретного виртуального терминала, кассы или системы. +* **Привязка:** TermNo определяет принадлежность к Юридическому лицу (ЮЛ), конкретной точке продаж (ТСП) и расчетному счету, на который будут поступать средства. +* **Лимиты:** Минимум 1 терминал на адрес ТСП, максимум — по запросу. +* **Применение:** + * Сохраняется в настройках терминала. + * Используется на прикладном уровне протокола совместно с сертификатом. + * **Обязателен** для генерации динамических QR-кодов и проверки статуса оплаты. + +--- + +## 3. Общий порядок работы + +### 3.1. Оплата покупки (C2B) +Процесс проведения оплаты через динамический QR-код: + +1. **Инициация:** Кассир вводит сумму (валюта и назначение платежа обычно подставляются автоматически). +2. **Запрос QR:** ТСП запрашивает динамический QR-код у Банка. +3. **Отображение:** ТСП выводит QR на экран или печатает пре-чек. +4. **Действия клиента:** + * Сканирует QR через банковское приложение. + * Подтверждает оплату. +5. **Проверка:** ТСП запрашивает подтверждение статуса платежа. +6. **Фискализация:** При получении статуса «Оплачено» ТСП печатает чек. + +**Обязательные реквизиты в чеке оплаты:** +* `qrcId` (Идентификатор QR-кода) +* Код транзакции СБП +* Дата и время операции + +--- + +### 3.2. Возврат покупки +Возврат средств имеет ряд технологических особенностей. + +> [!IMPORTANT] +> **Ограничения возврата:** +> * Возможен только при наличии чека и кода транзакции СБП. +> * Осуществляется только по номеру телефона плательщика. +> * Средства возвращаются только в тот же Банк-участник СБП, с которого была оплата. + +**Параметры для инициации возврата:** +* Сумма (полная или частичная) и валюта. +* Данные из чека: `qrcId`, Код транзакции, Дата оплаты. + +**Процесс подтверждения:** +1. Хост Банка проверяет наличие исходной операции. +2. Кассир проходит аутентификацию (ввод одноразового кода SMS/Push или иная проверка полномочий). +3. ТСП отправляет финальный запрос на возврат. + +**Реквизиты в чеке возврата:** +* Код транзакции `payrrn` +* Сумма возврата + +--- + +## 4. Работа с кассовыми ссылками + +Кассовая ссылка — это многоразовый QR-код, который активируется под конкретную покупку. + +### Жизненный цикл ссылки +1. **Регистрация:** ТСП через Агента регистрирует ссылку в ОПКЦ СБП. QR-код размещается в кассовой зоне. +2. **Активация:** В момент покупки ТСП отправляет запрос на активацию ссылки, передавая `сумму`, `валюту` и `назначение платежа`. + * *Совет:* Для получения уведомлений передавайте адрес `callback-url`. +3. **Оплата:** Клиент считывает статическую ссылку, которая после активации ведет на оплату конкретного счета. +4. **Деактивация:** Если оплата не состоялась, ТСП отправляет запрос на деактивацию. +5. **Изменение счета:** ТСП может изменить расчетный счет, привязанный к ссылке, через запрос к Агенту ТСП (автоматические уведомления об изменении не поддерживаются). + +--- + +## 5. Привязка счета и рекуррентные платежи + +Сценарии для реализации оплат «в один клик» или подписок. + +### Сценарии регистрации привязки +| Тип сценария | Описание | +| :--- | :--- | +| **Чистая привязка** | Регистрация QR-кода типа `03`. Клиент сканирует код только для привязки счета без оплаты. | +| **Оплата + Привязка** | При регистрации обычного QR на оплату передается параметр `subscriptionPurpose`. После оплаты банк предлагает клиенту привязать счет. | + +### Оплата по инициативе ТСП (Списание без участия клиента) +1. ТСП регистрирует QR для оплаты с привязанного счета. +2. ТСП направляет запрос на оплату в НСПК. +3. НСПК запрашивает подтверждение у Банка Плательщика. +4. При положительном ответе инициируется C2B операция, и Агент ТСП получает уведомление о финальном статусе. + +--- + +## Справочник параметров (Сниппеты данных) + +При формировании запросов используйте следующие ключевые поля: + +```json +// Пример ключевых полей для активации кассовой ссылки / оплаты +{ + "TermNo": "12345678", // Номер терминала + "amount": 10000, // Сумма в копейках/единицах + "currency": "RUB", // Валюта + "qrcId": "AD100000...", // ID QR-кода + "payrrn": "3021...", // Код транзакции (для возвратов) + "callbackUrl": "https://..." // Адрес для уведомлений +} +``` + +# Статический QR-код (СБП) + +Статический QR-код — это инструмент безналичной оплаты через Систему быстрых платежей (СБП), являющийся альтернативой эквайрингу. Изображение QR-кода остается неизменным, его можно распечатать и разместить в кассовой зоне. + +### Особенности +* **Варианты реализации:** + * С открытой суммой (вводит покупатель). + * С фиксированной суммой (задает продавец при генерации). +* **Способы оплаты:** Сканирование камерой смартфона или использование NFC-метки. +* **Скорость:** Средства поступают на счет продавца мгновенно. +* **Оборудование:** Терминал не требуется. + +--- + +## 1. Регистрация статического QR-кода + +Метод `GetQRCd` используется для формирования платежной ссылки и получения изображения QR-кода. + +### Параметры запроса +| Параметр | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCd`. | +| `TermNo` | String(20) | Y | Уникальный идентификатор терминала. | +| `qrcType` | String(2) | Y | Тип QR-кода. Для статического — `01`. | +| `amount` | Number | O | Сумма в копейках. Если не указана — сумма открытая. | +| `currency` | String(3) | O | Код валюты (например, `RUB`). | +| `paymentPurpose` | String(140) | O | Назначение платежа. | +| `width` / `height` | String | O | Размеры изображения QR-кода в пикселях. | +| `redirectUrl` | String(1024)| O | Ссылка для возврата клиента в приложение/на сайт ТСП. | +| `messageID` | String(1024)| O | Уникальный ID сообщения (GUID). Только латиница. | +| `queryData.notificationUrl` | String(512) | O | URL для получения уведомления о статусе оплаты. | + +### Пример запроса +```json +{ + "command": "GetQRCd", + "TermNo": "90080567", + "qrcType": "01", + "width": "600", + "height": "600", + "amount": 10000, + "currency": "RUB", + "paymentPurpose": "Оплата заказа №123", + "messageID": "550e8400-e29b-41d4-a716-446655440000", + "queryData": { + "notificationUrl": "https://yourserver.com/sbp/notify" + }, + "redirectUrl": "https://yourshop.ru/success" +} +``` + +### Параметры ответа +| Параметр | Тип данных | Назначение | +| :--- | :--- | :--- | +| `ErrorCode` | String | Код ответа (0 — успех). | +| `image` | String | Изображение QR-кода в формате BASE64. | +| `payload` | String | Платежная ссылка (содержимое QR-кода). | +| `qrcId` | String | Уникальный идентификатор QR-кода. | +| `status` | String | Статус регистрации ссылки (например, `CREATED`). | + +--- + +## 2. Нотификация о статусе оплаты + +После успешной оплаты Банк отправляет POST-запрос на `notificationUrl`, указанный при регистрации. + +### Параметры уведомления +| Параметр | Тип данных | Назначение | +| :--- | :--- | :--- | +| `qrcId` | String | Идентификатор QR-кода. | +| `trxId` | String | Уникальный ID платежа в НСПК. | +| `status` | String | `ACWP` — успех, `RJCT` — отклонено. | +| `amount` | Number | Сумма платежа в копейках. | +| `timestamp` | String | Время операции по Гринвичу (GMT). | +| `payerId` | String | Маскированный номер телефона плательщика. | + +### Пример уведомления +```json +{ + "command": "qrc/notification", + "qrcId": "AS10000NJTDV88TN82CRT8CG1AU690OF", + "trxId": "A31040920067662400000550448AD7B3", + "status": "ACWP", + "amount": 10000, + "timestamp": "2023-04-14T09:20:06.000Z", + "payrrn": "000051992395", + "TermNo": "90080567" +} +``` +*ТСП должно ответить HTTP-кодом `200 OK`.* + +--- + +## 3. Проведение возврата + +Возврат средств выполняется в два этапа. + +### 3.1. Проверка возможности возврата (`GetQRCreversalData`) +Используется для получения данных о плательщике и проверки доступности операции. + +**Запрос:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `qrcId` | Y | ID QR-кода из оригинального платежа. | +| `trxId` | Y | ID транзакции НСПК. | +| `amount` | O | Сумма возврата. Если пусто — полный возврат. | + +**Пример ответа:** +```json +{ + "ErrorCode": 0, + "payerBnkName": "Альфа-Банк", + "payerId": "*1779", + "trxDT": "20230414062006", + "message": "OK" +} +``` + +### 3.2. Выполнение возврата (`QRCreversal`) +Непосредственная инициация перевода средств клиенту. + +**Запрос:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `messageID` | Y | GUID, полученный в ответе `GetQRCreversalData`. | +| `queryData.notificationUrl` | O | URL для уведомления о статусе возврата. | + +--- + +## 4. Запрос статуса возврата + +Метод `GetQRCreversalStatus` используется для уточнения финального статуса операции возврата (B2C). + +### Параметры запроса +Для поиска операции необходимо передать одну из пар: +1. `payrrn` ИЛИ `originalTrxId` (для поиска исходного платежа). +2. `trxId` ИЛИ `messageID` (для идентификации самого возврата). + +### Статусы возврата в ответе +* `ACWP` — Возврат успешно завершен. +* `RJCT` — Операция отклонена. +* `NTST` — Статус неизвестен (в обработке). + +### Пример ответа +```json +{ + "ErrorCode": 0, + "amount": 10000, + "status": "ACWP", + "originalTrxId": "A31040920067662400000550448AD7B3", + "trxId": "B31071502287201D00001650448AD7B3" +} +``` + +--- +*Примечание: Все текстовые данные в запросах должны передаваться в кодировке UTF-8, формат передачи данных — JSON.* + +# Интеграция динамических QR-кодов (СБП) + +Оплата по динамическому QR-коду — это способ безналичной оплаты через Систему Быстрых Платежей (СБП). QR-код создается отдельно под каждую покупку, содержит сумму и реквизиты. Средства мгновенно поступают на счёт продавца. + +## 1. Регистрация динамического QR-кода +**Метод:** `GetQRCd` + +Используется для генерации QR-кода под конкретный заказ. + +### Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCd` | +| `TermNo` | String(20) | Y | Уникальный идентификатор терминала | +| `qrcType` | String(2) | Y | Тип QR-кода. Для динамического — `02` | +| `amount` | Number | Y | Сумма в минорных единицах (копейках) | +| `currency` | String(3) | Y | Код валюты (для рублей — `RUB`) | +| `OrderNumber` | String(1000)| O | Номер заказа (только латиница и цифры) | +| `paymentPurpose`| String(140) | O | Назначение платежа | +| `qrTtl` | String(6) | O | Срок жизни ссылки в минутах (мин. 1, рек. от 5) | +| `queryData.notificationUrl` | String(512) | O | URL для уведомления о статусе оплаты | +| `redirectUrl` | String(1024)| O | Ссылка для возврата клиента в приложение/сайт | +| `extJsonParams` | Object | O | Блок дополнительных параметров (JsonParam1-10) | + +**Для подписок (рекуррентных платежей):** +* `subscriptionServiceId`: Идентификатор привязки. +* `subscriptionServiceName`: Наименование привязки. + +### Пример запроса +```json +{ + "command": "GetQRCd", + "TermNo": "90080567", + "amount": "10000", + "currency": "RUB", + "qrcType": "02", + "qrTtl": "5", + "OrderNumber": "FYI123456", + "queryData": { + "notificationUrl": "https://sbp-payments.your-site.com/callback" + } +} +``` + +### Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String | Y | Код ответа (0 — успех) | +| `image` | String | Y | Изображение QR-кода в формате Base64 | +| `payload` | String | Y | Платежная ссылка СБП | +| `qrcId` | String | Y | Уникальный идентификатор QR-кода | +| `status` | String | Y | Статус регистрации (например, `CREATED`) | + +--- + +## 2. Запрос статуса оплаты +**Метод:** `GetQRCstatus` + +Направляется кассой/терминалом для проверки факта оплаты. +> **Важно:** Запрос следует направлять не ранее, чем через 10 секунд после формирования QR, и не чаще чем раз в 3 секунды. + +### Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `GetQRCstatus` | +| `TermNo` | String | Y | Идентификатор терминала | +| `qrcId` | String | Y/O | ID QR-кода (обязательно, если нет payrrn) | +| `payrrn` | String | Y/O | Референс запроса в системе Банка | + +### Возможные статусы (`status`) +1. `ACWP` (ACCEPTED) — Операция завершена успешно. +2. `RJCT` (REJECTED) — Операция отклонена. +3. `NTST` (NOT_STARTED) — Операция не найдена (нужен повтор запроса). +4. `RCVD` (RECEIVED) — Операция в обработке. + +### Пример ответа (Успех) +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + "trxId": "A3013090427361010000057B3DA2D4A7", + "amount": 10000, + "payerId": "*********1234" +} +``` + +--- + +## 3. Нотификация о финальном статусе +**Метод:** `qrc/notification` + +Запрос отправляется со стороны Банка на `notificationUrl` ТСП. + +### Формат уведомления +```json +{ + "command": "qrc/notification", + "qrcId": "AD100026KQ0ESJBV8OFPCG0U9K1H52UM", + "status": "ACWP", + "amount": "10000", + "trxId": "A3013090427361010000057B3DA2D4A7", + "timestamp": "2022-10-27T14:33:49.000Z" +} +``` +*ТСП должно ответить HTTP-кодом `200`.* + +--- + +## 4. Проведение возврата +Возврат может быть выполнен в два этапа (проверка + выполнение) или в один этап (при передаче `messageID`). + +### 4.1 Проверка возможности возврата (`GetQRCreversalData`) +Используется для получения данных о плательщике и проверки доступного остатка. + +### 4.2 Выполнение возврата (`QRCreversal`) +**Параметры запроса:** +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `QRCreversal` | +| `amount` | Number | O | Сумма возврата (если не указана — полный возврат) | +| `qrcId`/`trxId` | String | Y | Идентификаторы оригинальной операции | +| `ReturnRestAmount`| Boolean| O | Вернуть остаток доступных средств в ответе | + +### Пример ответа на возврат +```json +{ + "ErrorCode": 0, + "message": "Возврат проведен", + "amount": 10000, + "trxId": "A3024113609260070000086B8426B817", + "restAmount": "99.87" +} +``` + +--- + +## 5. История и статусы возвратов + +### Запрос истории (`GetQRCreversalHistory`) +Позволяет получить список всех попыток возврата по одной транзакции оплаты. + +**Пример структуры массива `refunds` в ответе:** +```json +"refunds": [ + { + "status": "ACWP", + "amount": 10000, + "trxId": "B51390823097450W0000180011510503", + "trxDT": "20250519082345" + }, + { + "status": "RJCT", + "amount": 10000, + "trxId": "A4327120041167130000020011381101" + } +] +``` + +--- + +## 6. Нотификация о возврате +**Метод:** `b2c-refund/notification` + +Банк уведомляет систему ТСП о финальном статусе операции возврата. + +### Пример уведомления +```json +{ + "command": "b2c-refund/notification", + "status": "ACWP", + "amount": "10000", + "originalTrxId": "X1A2S3D5F6G7H8J9K0C4S5C6D7V5D1K2", + "trxId": "A3024113609260070000086B8426B817" +} +``` + +--- + +## Примечания +* **Формат данных:** Все текстовые данные в ответах передаются в формате `urlencoded`. +* **Суммы:** Все суммы в запросах передаются как целые числа в копейках. +* **Ошибки:** Список кодов ошибок приведен в Приложении №2 (согласно основной документации Банка). +* **Успешная оплата:** Считается подтвержденной только при получении статуса `ACWP` и наличии `trxId`. + +# Кассовая платёжная ссылка СБП: Техническая документация + +**Кассовая платёжная ссылка** — это гибридное решение, объединяющее преимущества статического и динамического QR-кодов. QR-код остается неизменным (его можно распечатать один раз), но сумма оплаты передается с кассы в момент покупки, что исключает ошибки ручного ввода со стороны клиента. + +## Общие положения +* Для каждой кассы/терминала создается уникальная ссылка. +* Сумма передается в **минорных единицах** (копейках). +* Текстовые данные в ответах передаются в формате `urlencoded`. + +--- + +## 1. Регистрация кассовой платёжной ссылки +Метод `RegCashQRc` используется для генерации постоянного QR-кода для терминала. + +### Параметры запроса +| Параметр | Тип | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `RegCashQRc` | +| `TermNo` | String | Y | Уникальный ID терминала (до 20 симв.) | +| `mediaType` | String | N | Тип картинки (напр., `image/png`) | +| `width` | String | N | Ширина изображения | +| `height` | String | N | Высота изображения | +| `redirectUrl` | String | N | Ссылка для возврата клиента в приложение ТСП | +| `qrcId` | String | N | ID для привязки предвыпущенных NFC-табличек | + +**Пример запроса:** +```json +{ + "command": "RegCashQRc", + "TermNo": "90080567", + "mediaType": "image/png", + "width": "600", + "height": "600", + "redirectUrl": "https://exampletsp.io/callback" +} +``` + +--- + +## 2. Активация ссылки (Передача суммы) +Метод `ActivateCashQRc` вызывается кассой в момент совершения покупки для установки суммы и параметров платежа. + +### Параметры запроса +| Параметр | Тип | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `ActivateCashQRc` | +| `TermNo` | String | Y | ID терминала | +| `qrcId` | String | Y | ID QR-кода | +| `amount` | Number | Y | Сумма в копейках | +| `currency` | String | N | Валюта (по умолчанию `RUB`) | +| `qrTtl` | String | N | Срок жизни активации (5–20 мин) | +| `queryData.notificationUrl` | String | N | URL для уведомления об оплате | + +**Пример запроса:** +```json +{ + "command": "ActivateCashQRc", + "TermNo": "90080567", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + "amount": 10000, + "currency": "RUB", + "qrTtl": "5", + "queryData": { + "notificationUrl": "https://sbp-payments.your-site.ru" + } +} +``` + +--- + +## 3. Проверка статуса оплаты +Метод `GetQRCstatus` используется для получения финального статуса транзакции. Рекомендуется запрашивать не ранее 10 сек. после активации и не чаще раза в 3 сек. + +### Статусы оплаты (поле `status`) +* **ACWP** (ACCEPTED) — Оплата успешно завершена. +* **RJCT** (REJECTED) — Операция отклонена. +* **NTST** (NOT_STARTED) — Оплата еще не инициирована. +* **RCVD** (RECEIVED) — В обработке. + +**Пример ответа (Успех):** +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "trxId": "A30180803159571F0000097B3DA2D4A7", + "amount": 10000, + "payerId": "*********1234", + "payrrn": "000056251465" +} +``` + +--- + +## 4. Деактивация ссылки +Метод `DelCashQRc` используется для досрочной отмены ожидания оплаты (например, если клиент отказался от покупки). + +**Пример запроса:** +```json +{ + "command": "DelCashQRc", + "TermNo": "90080567", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9" +} +``` + +--- + +## 5. Возврат платежа +Возврат по СБП выполняется в два этапа (или в один при наличии `messageID`). + +### Этап 1: Проверка возможности возврата (`GetQRCreversalData`) +Позволяет узнать доступный остаток и получить данные для проведения возврата. + +### Этап 2: Проведение возврата (`QRCreversal`) +**Пример запроса на возврат:** +```json +{ + "command": "QRCreversal", + "TermNo": "90080567", + "payrrn": "000056251465", + "amount": 10000, + "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8" +} +``` + +--- + +## 6. Нотификации (Webhooks) +Банк отправляет POST-запросы на ваш `notificationUrl` при изменении статуса оплаты или возврата. + +### Уведомление об оплате (`qrc/notification`) +```json +{ + "command": "qrc/notification", + "qrcId": "BS1R001P1UIGJCFJ9RDQ8974M1I4CJO9", + "status": "ACWP", + "amount": 10000, + "trxId": "A30180803159571F0000097B3DA2D4A7" +} +``` + +--- + +## 7. Изменение параметров ссылки +Метод `ChangeAccForCashQRc` позволяет перепривязать QR-код к другому счету, терминалу или изменить `redirectUrl`. + +| Параметр | Назначение | +| :--- | :--- | +| `NewTermNo` | Перенос на новый ID терминала | +| `NewMerchantId` | Перенос на другую торговую точку | +| `account` | Смена расчетного счета | + +--- + +## Приложение: Коды ошибок (ErrorCode) +| Код | Описание | +| :--- | :--- | +| `0` | Успешно | +| `3` | Не передан обязательный параметр | +| `16` | Некорректный TermNo | +| `41` | Некорректный qrcId | +| `301` | Превышен временной диапазон поиска | +| `RQ05019` | Не передан параметр amount при активации | + +> **Примечание:** При получении статуса `NTST` необходимо продолжать опрос статуса до получения финального результата (`ACWP` или `RJCT`). + +# Привязка счёта и подписки СБП: Техническая документация + +Данный функционал позволяет ТСП (Торгово-сервисным предприятиям) выполнять привязку банковского счёта клиента для проведения последующих платежей без участия плательщика (рекуррентные платежи, оплата в один клик). + +--- + +## 1. Привязка счёта без оплаты +Используется для регистрации QR-кода, целью которого является только установление связки между счётом клиента и ТСП. + +### 1.1. Метод `RegQRcSub` + +**Параметры запроса:** + +| Параметр | Тип | Обяз. | Описание | +| :--- | :--- | :---: | :--- | +| `command` | String | Да | Тип запроса. Константа: `RegQRcSub`. | +| `TermNo` | String | Да | Уникальный идентификатор терминала. | +| `qrcType` | String | Да | Тип QR-кода. Константа: `03`. | +| `subscriptionPurpose` | String | Да | Цель привязки. Отображается клиенту в приложении банка. | +| `queryData.notificationUrl` | String | Да | URL для получения уведомления о результате привязки. | +| `qrTtl` | String | Нет | Срок жизни ссылки в минутах (1 — 129 600). По умолчанию: 4320 (3 суток). | +| `redirectUrl` | String | Нет | Ссылка для возврата клиента в приложение/на сайт ТСП. | +| `subscriptionServiceId` | String(32) | Нет | Идентификатор сервиса подписки (используется с `subscriptionServiceName`). | +| `subscriptionServiceName`| String(70) | Нет | Наименование сервиса подписки. | + +**Пример запроса:** +```json +{ + "command": "RegQRcSub", + "TermNo": "90080567", + "qrTtl": "10", + "qrcType": "03", + "subscriptionPurpose": "Подписка на оплату услуг Интернет 500р./мес.", + "queryData": { + "notificationUrl": "https://sbp-subscription.example.com" + }, + "redirectUrl": "https://exampletsp.io/callback" +} +``` + +**Параметры ответа:** + +| Параметр | Описание | +| :--- | :--- | +| `ErrorCode` | Код ответа (0 или RQ00000 — успех). | +| `qrcId` | Идентификатор QR-кода. | +| `payload` | Платежная ссылка для формирования QR или перехода. | +| `payrrn` | Референс запроса в системе Банка. | + +--- + +### 1.2. Нотификация о результате привязки (`subscription/notification`) +Банк отправляет POST-запрос на `notificationUrl` ТСП. + +**Параметры нотификации:** +* `status`: `ACWP` (оформлено) или `RJCT` (отказ). +* `subscriptionToken`: Уникальный токен привязки (необходим для будущих оплат). +* `memberId`: Идентификатор банка плательщика. + +> **Важно:** Значения `subscriptionToken` и `memberId` необходимо сохранить. Без них проведение платежей по инициативе ТСП невозможно. + +--- + +## 2. Оплата с последующей привязкой счёта +Позволяет клиенту совершить первую покупку и одновременно разрешить ТСП списывать средства в будущем. + +### 2.1. Метод `GetQRCd` (Тип 02) + +Для этого сценария используется стандартный метод генерации QR, но с обязательным заполнением поля `subscriptionPurpose`. + +**Ключевые параметры:** +* `qrcType`: `02` (динамический QR). +* `amount`: Сумма первого платежа в копейках. +* `subscriptionPurpose`: Описание подписки (наличие этого поля активирует сценарий привязки). +* `queryData.notificationUrl_sub`: (Опционально) Отдельный URL для уведомления именно о привязке. + +**Логика уведомлений:** +1. При успешной операции ТСП получает **два** callback-уведомления: + - О статусе платежа (`qrc/notification`). + - О статусе привязки (`subscription/notification`). +2. Если платеж прошел, но клиент отказался от привязки — придет уведомление об успехе оплаты и уведомление об отказе в подписке. + +--- + +## 3. Оплата с привязанного счёта (по инициативе ТСП) +Сценарий "бесшовной" оплаты без участия клиента. Проводится в два этапа. + +### Этап 1: Генерация ссылки через `GetQRCd` +Создается технический QR-код (тип `02`), к которому будет "привязан" платеж. +* `paymentPurpose`: Обязательно для заполнения. +* `amount`: Сумма списания. + +### Этап 2: Запрос на списание `QRCSubPayPetition` +ТСП отправляет команду банку на исполнение платежа, используя полученный ранее токен. + +**Параметры запроса:** +| Параметр | Обяз. | Описание | +| :--- | :---: | :--- | +| `command` | Да | `QRCSubPayPetition` | +| `subscriptionToken` | Да | Токен, полученный при регистрации привязки. | +| `SenderMemberId` | Да | Идентификатор банка плательщика (`memberId`). | +| `qrcId` | Да | ID QR-кода, созданного на Этапе 1. | + +**Пример запроса:** +```json +{ + "command": "QRCSubPayPetition", + "TermNo": "90080567", + "subscriptionToken": "70LSS7DN18SJQRS10006DNPKLJL24B05", + "SenderMemberId": "100000000008", + "qrcId": "AD10000BBJKO23GB98LA1FGBRIHH3K89" +} +``` + +### 3.1. Статусы решения банка (`resolution/notification`) +После запроса на списание банк присылает уведомление с результатом: + +| Код | Описание | +| :--- | :--- | +| `RQ00030` | **Успех.** Согласие на проведение платежа. | +| `RQ05031` | Отказ: Привязка не найдена (клиент мог её удалить). | +| `RQ05060` | Отказ: Недостаточно средств. | +| `RQ05061` | Отказ: Превышен лимит СБП. | +| `RQ05063` | Отказ: Подозрение на мошенничество. | + +--- + +## 4. Запрос статуса привязки +Если ТСП не получило callback, можно запросить статус привязки вручную. + +### Метод `GetQRCSubStatus` + +**Запрос:** +```json +{ + "command": "GetQRCSubStatus", + "TermNo": "90080567", + "qrcId": "BB1S002PRSK6SR3E9R7P0H077UKN1QVF" +} +``` + +**Ответ (успешная привязка):** +```json +{ + "ErrorCode": 0, + "status": "ACWP", + "subscriptionToken": "70LSS7DN18SJQRS10006DNPKLJLAGT77", + "memberId": "600000000015", + "message": "OK" +} +``` + +--- + +## Важные примечания для разработчиков + +1. **Лимиты:** Оплата с привязанного счета возможна на сумму до **1 000 000 руб.** за одну операцию. +2. **Кодировка:** Текстовые данные в ответах могут передаваться в формате `urlencoded` (например, `%u0423%u0441%u043F%u0435%u0445` для слова "Успех"). +3. **Безопасность:** Система ТСП должна игнорировать неизвестные дополнительные параметры в уведомлениях от НСПК/Банка, не считая их ошибкой. +4. **Хранение данных:** Потеря `subscriptionToken` делает невозможным рекуррентное списание. В этом случае потребуется повторная привязка через QR-код. + +# Цифровой рубль: Техническая документация по интеграции + +Цифровой рубль (ЦР) — это третья форма национальной валюты, дополняющая наличные и безналичные средства. Счета цифрового рубля открываются на платформе Центрального банка, а доступ к ним осуществляется через мобильные приложения и интернет-банки коммерческих банков. + +Прием платежей в ЦР осуществляется в рамках **Универсального платёжного кода (УПК)**. + +--- + +## 1. Динамический QR-код (Одноразовый УПК) + +Динамический код формируется под конкретную операцию с фиксированной суммой. + +### 1.1. Регистрация динамического УПК +Для генерации кода можно использовать существующий метод `GetQRCd` или специализированный метод `ReqUniQr`. + +#### Метод `ReqUniQr` +Запрос направляется ТСП в Банк для регистрации универсальной платёжной ссылки в API СБП. + +**Параметры запроса:** + +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String | Y | Константа `ReqUniQr` | +| `TermNo` | String | Y | Уникальный идентификатор терминала | +| `amount` | Number | O* | Сумма в копейках (обязательна для `uniQrType = 02`) | +| `uniQrType` | String | Y | Тип ссылки: `01` — многоразовая, `02` — одноразовая | +| `mediaType` | String | O | Расширение QR-кода (напр., `image/png`) | +| `width` / `height` | String | O | Размеры изображения в пикселях | +| `paymentPurpose` | String | O | Назначение платежа | +| `redirectUrl` | String | O | URL для возврата в приложение ТСП (ASCII/RFC3986) | +| `messageID` | String | O | Уникальный GUID сообщения | +| `qrTtl` | String | O | Срок жизни ссылки в минутах | +| `queryData.notificationUrl` | String | O | URL для уведомления о статусе оплаты | + +**Пример запроса:** +```json +{ + "command": "ReqUniQr", + "TermNo": "90080567", + "amount": "10000", + "uniQrType": "02", + "redirectUrl": "https://alfabank.ru/sme/payservice/sbp/", + "mediaType": "image/png", + "width": "600", + "height": "600", + "messageID": "f9aa54ff-a615-44b8-aa6c-acab655c89f8", + "queryData": { + "notificationUrl": "https://sbp-payments", + "SenderFIO": "Иванов Иван Иванович" + } +} +``` + +**Параметры ответа:** +- `ErrorCode`: `0` — успех. +- `payload`: Платёжная ссылка. +- `image`: Изображение QR-кода в Base64. +- `uniQrId`: Идентификатор ссылки. +- `status`: Статус (обычно `CREATED`). + +--- + +### 1.2. Проверка статуса оплаты динамического УПК +Используется метод `GetUniQrStatus`. + +**Специфические статусы для Цифрового рубля:** +* `ENDD`: Платёж в ЦР обработан, но финальный результат (успех/отказ) пока неизвестен. +* `ACDR`: Платёж в ЦР успешно выполнен (аналог `ACWP` для СБП). + +**Структура блока `data` (массив Record) в ответе:** + +| Ключ | Описание | +| :--- | :--- | +| `paymentServiceId` | `PS0000000001` (СБП) или `PS0000000002` (ЦР) | +| `status` | `NTST` (не начат), `RCVD` (в процессе), `ACWP` (успех СБП), `RJCT` (отказ), `ENDD` (ЦР в обработке), `ACDR` (успех ЦР) | + +--- + +## 2. Кассовая платёжная ссылка (Многоразовый УПК) + +Многоразовый код, который обычно размещается в кассовой зоне. + +### 2.1. Регистрация кассового УПК +Метод: `RegCashUniQr`. + +**Особенности:** +* Позволяет привязать конкретный `qrcId`. +* В настройках ТСП на стороне Банка должен быть обязательно указан счет ЦР (`accountDR`). + +**Пример ответа:** +```json +{ + "ErrorCode": "0", + "message": "OK", + "TermNo": "90080567", + "payload": "https://qr.nspk.ru/BS2R003FS8EFGAVM852PQS13N894HDLU?type=01...", + "image": "iVBORw0KGgoAAAANSUhEUgAAAlg...", + "qrcId": "BS2R003FS8EFGAVM852PQS13N894HDLU", + "status": "CREATED" +} +``` + +--- + +### 2.2. Изменение параметров кассового УПК +Метод `ChangeAccForCashUniQr` позволяет обновить привязанные счета или параметры терминала без смены самого QR-кода. + +**Ключевые параметры для изменения:** +* `account`: Новый счет для СБП. +* `accountDR`: Новый счет для Цифрового рубля (строго 55 символов). +* `NewTermNo`: Смена ID терминала. +* `NewMerchantId`: Смена ID мерчанта в НСПК. + +--- + +### 2.3. Проверка статуса кассового УПК +Метод: `GetCashUniQrStatus`. + +**Важные поля ответа:** +* `paymentServiceId`: Определяет, как заплатил клиент (`PS0000000002` — Цифровой рубль). +* `cashRegisterQrcStatus`: Статус самой ссылки (`WAITING_PAYMENT`, `IN_PROGRESS`, `DEACTIVATED`). + +--- + +## 3. Нотификация об исполнении перевода (C2B) + +Сообщение отправляется со стороны Банка на сервер ТСП при получении финального статуса платежа. + +**Метод:** `paymentDR/notification` (POST запрос) + +**Параметры запроса:** + +| Код ключа | Тип данных | Назначение | +| :--- | :--- | :--- | +| `command` | String | `paymentDR/notification` | +| `uniQrId` | String | Идентификатор платежа | +| `operationId` | String | ID операции на платформе ЦР | +| `status` | String | Статус (напр. `ACWP` или `RCVD`) | +| `amount` | String | Сумма в рублях (с разделителем-точкой) | +| `timestamp` | ISO8601 | Дата и время операции | +| `payrrn` | String | Референс платежа | + +**Пример нотификации:** +```json +{ + "command": "paymentDR/notification", + "uniQrId": "AD2000670LSS7DN18SJQDNP4B05KLJL1", + "operationId": "546464AX45546", + "status": "ACWP", + "amount": "10241.21", + "timestamp": "2024-08-01T10:15:00.000Z", + "payrrn": "102345678912", + "TermNo": "90080567", + "merchantName": "Рога и Копыта", + "purpose": "Кофе и булочка" +} +``` + +**Ожидаемый ответ от ТСП:** +* `HTTP 200 OK` — уведомление успешно принято. +* `HTTP 500` — внутренняя ошибка (будет произведена повторная попытка). + +--- + +## Приложение: Справочник статусов (status) + +| Код | Описание | Применимость | +| :--- | :--- | :--- | +| **NTST** | Платёж не начат | СБП / ЦР | +| **RCVD** | Платёж инициирован / в обработке | СБП / ЦР | +| **ACWP** | Платёж успешно выполнен | СБП | +| **RJCT** | Платёж отклонён | СБП | +| **ENDD** | Платёж обработан (результат уточняется) | **ЦР** | +| **ACDR** | Платёж успешно выполнен | **ЦР** | + +# Дополнительные методы API СБП (Альфа-Банк) + +Данный документ содержит описание дополнительных методов API для работы с Системой Быстрых Платежей (СБП) через платежный шлюз (ПШ) Альфа-Банка. + +> **Примечание:** Таблицы кодов ответов (`ErrorCode`) и их расшифровок приведены в Приложении №2 к основной документации. + +--- + +## 1. Запрос списка банков-участников СБП (`GetBankList`) + +Метод используется ТСП для получения актуального списка банков, поддерживающих оплату через СБП. + +### 1.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `GetBankList` | +| `messageID` | String (ans-1..1024) | N | Уникальный идентификатор сообщения (GUID) | +| `BankMemberIdFilter` | String (n-11) | N | Фильтр по ID участника СБП (если нужен только один банк) | + +**Пример запроса:** +```json +{ + "command": "GetBankList" +} +``` + +### 1.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | +| `BankList` | Array | N | Коллекция банков-участников | +| `BankList.BankName` | String (an-50) | N | Наименование банка | +| `BankList.BankID` | String (an-12) | N | Идентификатор участника СБП в НСПК | +| `BankList.BankBIK` | String (n-9) | N | БИК банка (если передан из НСПК) | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "message": "Запрос обработан успешно", + "BankList": [ + { + "BankName": "Наименование банка 1", + "BankID": "10000001100", + "BankBIK": "044525823" + }, + { + "BankName": "Наименование банка N", + "BankID": "10000001145", + "BankBIK": "044525829" + } + ] +} +``` + +--- + +## 2. Блокирование QR-кода (`BlockQRcId`) + +Запрос направляется для блокировки ранее сгенерированного QR-кода любого типа. + +### 2.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `BlockQRcId` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | +| `reason` | String (ans-1024) | N | Причина блокировки | + +**Пример запроса:** +```json +{ + "command": "BlockQRcId", + "TermNo": "90080567", + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV", + "reason": "Заказ 12345 направлен в стоп-лист" +} +``` + +### 2.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | + +**Пример успешного ответа (200 OK):** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK" +} +``` + +--- + +## 3. Разблокирование QR-кода (`UnblockQRcId`) + +Запрос используется для восстановления активности ранее заблокированного QR-кода. + +### 3.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `UnblockQRcId` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | + +**Пример запроса:** +```json +{ + "command": "UnblockQRcId", + "TermNo": "90080567", + "qrcId": "BS1R003FN6RS6HL48QMBFVO5C4K9GQRV" +} +``` + +### 3.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK" +} +``` + +--- + +## 4. Список заблокированных QR-кодов (`GetBlockedQRcIdList`) + +Запрос позволяет получить перечень всех заблокированных QR-кодов по конкретному терминалу или кассе. + +### 4.1. Параметры запроса +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `command` | String (an-1..50) | **Y** | Тип запроса. Константа: `GetBlockedQRcIdList` | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | + +**Пример запроса:** +```json +{ + "command": "GetBlockedQRcIdList", + "TermNo": "90080567" +} +``` + +### 4.2. Параметры ответа +| Код ключа | Тип данных | Обяз. | Назначение | +| :--- | :--- | :---: | :--- | +| `ErrorCode` | String (an-20) | **Y** | Код ответа | +| `message` | String (ans-1024) | **Y** | Расшифровка кода ответа | +| `TermNo` | String (an-20) | **Y** | Уникальный идентификатор терминала | +| `QRcIdList` | Collection | N | Список заблокированных QR-кодов | +| `QRcIdList.qrcId` | String (an-32) | **Y** | Идентификатор QR-кода | +| `QRcIdList.reason` | String (ans-1024) | N | Причина блокировки | +| `QRcIdList.date` | String (an-20) | **Y** | Дата и время блокировки | + +**Пример успешного ответа:** +```json +{ + "ErrorCode": 0, + "TermNo": "90080567", + "message": "OK", + "QRcIdList": [ + { + "date": "2024-04-18 17:17:45", + "qrcId": "BD100000K5II0G369JHR3KBA6SM3FD3V", + "reason": "Заказ 12345 направлен в стоп-лист" + }, + { + "date": "2024-05-01 19:07:15", + "qrcId": "BD100002JN871TSC9SJB7HPVRFD3HQ8T", + "reason": "Заказ 96780 направлен в стоп-лист" + } + ] +} +``` + +--- + +## Обработка ошибок (Общий формат) + +В случае ошибки (например, `400 Bad Request`), шлюз возвращает JSON следующего вида: + +```json +{ + "ErrorCode": "Код ошибки", + "message": "Расшифровка причины ошибки" +} +``` + +# Приложения к технической спецификации СБП + +## Приложение 1. Формат Payload + +В Системе быстрых платежей (СБП) используется формат двухмерного кода **QR Code (ISO/IEC 18004-2015)**. Payload (полезная нагрузка) может быть представлен в двух вариантах. + +### Варианты Payload +* **Короткий вариант:** `https://{HOST}/{QR_ID}` +* **Длинный вариант:** `https://{HOST}/{QR_ID}?type={QR_TYPE}&bank={MEMBER_ID}&sum={SUM}&cur={CUR}&crc={CRC}` + +### Описание параметров URL-based payload + +| Параметр | Описание | Обяз. | Формат | +| :--- | :--- | :---: | :--- | +| **HOST** | `qr.nspk.ru` — для QR_TYPE 01 и 02
`sub.nspk.ru` — для QR_TYPE 03 | y | String | +| **QR_ID** | Идентификатор зарегистрированного QR-кода в СБП | y | String (32 симв.) | +| **QR_TYPE** | Тип QR-кода:
01 — QR Static (наклейка)
02 — QR Dynamic (на кассе)
03 — QR-Subscription (привязка счета) | y | String (2 цифры) | +| **MEMBER_ID** | Идентификатор Банка Получателя (ТСП) | y | String (12 симв.) | +| **SUM** | Сумма в копейках. Обязательна для типа 02. Отсутствует для типа 03. | y/o | String (до 12 цифр) | +| **CUR** | Валюта операции (обязательна, если присутствует SUM) | y/o | String (3 симв.) | +| **CRC** | Значение контрольной суммы | y | String (4 симв.) | + +--- + +## Приложение 2. Описание кодов ответа + +Полный перечень кодов представлен на сайте НСПК. Коды, не описанные ниже, следует обрабатывать как **техническую (системную) ошибку**. + +### Общие коды ошибок системы + +| Код | Сообщение / Описание | +| :--- | :--- | +| **0** | **OK** (Успешно) | +| **-999** | Прочее сообщение FSCryptoProxy | +| **-71** | Неверные данные Basic-авторизации запроса | +| **-9** | Система перегружена. Повторите запрос позже | +| **-7** | Неверная подпись сообщения (ошибка ключей) | +| **-6** | Не передана подпись в заголовке Authorization | +| **-1** | Возникли проблемы при обработке запроса | +| **1** | Внутренняя ошибка | +| **2** | Терминал не обнаружен | +| **8** | Таймаут ответа | +| **25** | Терминал заблокирован | +| **1001** | Сервис временно недоступен | + +### Коды ОПКЦ СБП (RQ-серия) + +| Код | Описание | +| :--- | :--- | +| **RQ00000** | Запрос обработан успешно | +| **RQ03001** | Ошибка валидации. Неверный формат запроса | +| **RQ05002** | Участник (memberId) не найден в СБП | +| **RQ05005** | ТСП (merchantId) не зарегистрировано в СБП | +| **RQ05009** | Сумма (amount) меньше минимально допустимой | +| **RQ05010** | Сумма (amount) больше максимально допустимой | +| **RQ05014** | Идентификатор qrcId не найден | +| **RQ05032** | Отказ Банка Плательщика в выполнении платежа | +| **RQ05040** | Сумма возврата превышает сумму исходной операции | +| **RQ07999** | Техническая ошибка | + +--- + +### Ошибки по конкретным методам + +#### Метод `GetQRCd` (Запрос QR-кода) +| Код | Описание | +| :--- | :--- | +| **3** | Не заполнены данные запроса | +| **28** | Запрос QR-кода не удался, не получен QR_ID | +| **301** | Некорректно заполнены данные | +| **999*** | Неизвестная ошибка. Требуется уточнение статуса | + +#### Метод `GetQRCstatus` (Статус платежа) +| Код | Описание | +| :--- | :--- | +| **4** | Не передан qrcId или payrrn | +| **5** | Не получены данные от СБП | +| **18** | Платеж не найден в запросах B07, B23 | + +#### Методы возврата (`GetQRCreversalData`, `QRCreversal`) +| Код | Описание | +| :--- | :--- | +| **12** | Не найдены данные для возврата | +| **20** | Получен отказ на запрос возврата | +| **22** | Несоответствие payrrn и qrcId в запросе | +| **27** | Возврат невозможен: счет зачисления не равен счету списания | +| **121** | Операция оплаты еще не имеет финального статуса | +| **201** | Отказ: Недостаточно средств на счете для возврата | + +--- + +### Коды callback-уведомлений (Оплата с привязанного счета) + +Используются в методе `resolution/notification`. + +| Код | Описание | +| :--- | :--- | +| **RQ05060** | Недостаточно денежных средств | +| **RQ05061** | Превышен лимит по сумме операций СБП | +| **RQ05063** | Подозрение в мошенничестве (Anti-fraud) | +| **RQ05065** | Счет заблокирован | +| **RQ05067** | Запрещено по требованию законодательства | + +> **Примечание:** Использование кода `RQ05032` допускается не более чем в 20% случаев от общего числа отказов Банка Плательщика. + +--- + +## Приложение 3. Пояснение для колонки «Required» + +| Метка | Значение | +| :---: | :--- | +| **y** | **Yes** — обязательное поле | +| **o** | **Optional** — опциональное поле | +| **y/o** | **Conditional** — условно обязательное (зависит от условий запроса) | + +--- + +## Приложение 4. Типы данных + +| Нотация | Описание | +| :--- | :--- | +| **a** | Символы латинского (A-Z, a-z) и русского (А-Я, а-я) алфавитов. | +| **n** | Цифры 0-9. | +| **an** | Буквенно-цифровой формат (смесь **a** и **n**). | +| **ans** | Буквенно-цифровой формат со спецсимволами (пробел, пунктуация, знаки `№`, `%` и т.д.). | + +**Кодировка:** Все данные передаются в кодировке **UTF-8**. + +]]> + +<_1_main_md> + signature64.txt + +openssl x509 -in client.crt -pubkey -noout > signing-pub.key + +openssl dgst -sha256 -signature signature.txt -verify signing-pub.key block.txt + +Content-Type: application/x-www-form-urlencoded + +Authorization: QMm5QWnAAj8Tp1hoIvGf1Hv7RPBoGgsDyGiR5GQ2v/MaS7Yaix6LDwAcry0UBWDZzqle2hx2fC7WbWkxXGvxK2Hcx + +key-name: c2b-tsp-test + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 5/7 + +Body: + +Как провести тестовую оплату + +1. Откройте на смартфоне ссылку https://testpay.alfabank.ru/sbp-page и нажмите Сканировать QR + +2. Наведите камеру смартфона на QR-код + +3. Нажмите Произвести оплату. +Готово: оплата на тестовом контуре выполнена. Переходить в выбор банков не надо. + +{"command":"GetQRCd","TermNo":"30000018","qrcType":"01","amount":"100","currency":"RUB","paymentPurpose" + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 6/7 + +https://testpay.alfabank.ru/sbp-page + +Получение статуса платежа по QR-коду, который уже оплачен + +Получить статус платежа по QR-коду можно с помощью запроса GetQRCstatus или callback-уведомления от ПШ. + +Запрос GetQRCstatus позволяет получить статус по оплаченному динамическому QR-коду, кассовой платёжной ссылке или при опла + +Callback-уведомление уходит по оплаченному статическому и динамическому QR-коду, по кассовой платёжной ссылке или при опла + +Чтобы получать callback-уведомления, торгово-сервисному предприятию (далее — ТСП) необходимо направить на email acquiring@alf + +Сервер на стороне ТСП должен быть публичным, иметь протокол HTTPS и 443 порт. + +Адреса, с которых ПШ отправляет callback-уведомления: 217.12.97.124, 217.12.101.32. + +Дополнительная информация по вызову метода GetQRCstatus + +• В интеграционном тестовом окружении для метода GetQRCstatus введено ограничение частоты запросов: не более 4 запросов в м + +• Ограничение введено в связи с лимитами на стороне НСПК (Национальная система платёжных карт): общий лимит — 60 запросов в + +• Чтобы исключить паразитический/избыточный трафики обеспечить стабильность работы тестового контура, мы выделили для да + +• При превышении лимита запросы будут отвергаться кодом 429 (Too Many Requests). + +Переход на промышленную среду + +Чтобы перейти на промышленную среду, необходимо заключить сделку по СБП с Альфа-Банком и запросить боевые доступы — для + +Пример письма есть в разделе Аутентификация на промышленной среде + +Срок, за который банк предоставит боевые данные, — до трёх рабочих дней. + +12/23/25, 11:20 AM Главная + +https://alfabank.ru/sme/payservice/sbp/docs/welcome/ 7/7 + +mailto:acquiring@alfabank.ru + + +]]> + +<_2_general_provisions_md> + + +<_3_static_QR_cods_md> + + +<_4_dynamic_QR_cods_md> + + +<_5_cache_payment_link_SBP_md> + + +<_6_link_account_subscription_SBP_md> + + +<_7_digital_rubble_md> +) + +status String (an‐20) o Статус платежа на ПлЦР + +• если заполнено значение настройки ACWPstatusDR, то передаётся значение, указанное + +• «RCVD» — Перевод УПК в процессе обработки + +amount String (an‐1…12) o Сумма платежа в рублях с копейками + +timestamp YYYY-MM-DDThh:mm:ss[.SSS] o Дата и время исполнения распоряжения на ПлЦР + +payrrn String (n‐12) y Референсный номер платежа + +BatchId String (n‐4…8) y Уникальный идентификатор смены (если смена терминала открыта) + +TermNo String (an‐20) y Уникальный идентификатор терминала в AWGW + +CreditDatePos String (ans 1‐256) y Дата операции, установленная Банком Получателя в ходе обработки уведомления НСПК (опре + +merchantName ? y Наименование ТСП + +purpose String (ans‐210 y Назначение платежа + +b) Примерный формат запроса: + +8 "accountDR": "g.ab.cbrdc.wlt.clt.abcd0123-ab12-4a12-89ab-abcdef01234G", + +9 "status": "UPDATED", + +10 "merchantId": "MA0000020651" + +11 } + +{ + + "ErrorCode": "Код ответа", + + "message": "Расшифровка кода ответа" + +} + +1 { + +2 "command": "paymentDR/notification", + +3 "uniQrId": "AD2000670LSS7DN18SJQDNP4B05KLJL1", + +4 "operationId": "546464AX45546", + +5 "status": "ACWP", + +6 "amount": "10241.21", + +7 "timestamp": "2024-08-01T10:15:00.000Z", + +8 "payrrn": "102345678912", + +9 "BatchId": "998844", + +10 "TermNo": "90080567", + +11 "CreditDatePos": "20240802", + +12 "merchantName": "Рога и Копыта", + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 12/13 + +В ответ ожидается: + +• http-код «200» — Успешный ответ (Уведомление получено) + +• http-код «500» — Внутренняя ошибка + +13 "purpose": "Кофе и булочка" + +14 } + +12/23/25, 11:24 AM Цифровой рубль + +https://alfabank.ru/sme/payservice/sbp/docs/digital-rub/?rp-menuOpen=1 13/13 + + +]]> + +<_8_additional_methods_API_md> + + +<_9_appendix_md> + + +1 Внутренняя ошибка <...> + +3 Не заполнены данные: <...> + +8 Таймаут ответа, попробуйте позже + +26 Ошибка идентификации + +28 Запрос QR-кода не удался, не был получен Идентификатор QR-кода + +301 Некорректно заполнены данные данные: <...> + +100 Ошибка во время выполнения SQL-запроса для поиска AccountDR для TermNo= + +101 Ошибка во время выполнения SQL-запроса для проверки isUniQR для QrcId = + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Ошибки по методу GetQRCstatus + +Код Описание + +-1 Возникли проблемы при обработке запроса: <...> + +1 Внутренняя ошибка <...> + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 5/8 + +Код Описание + +2 Терминал <номер терминала> не обнаружен + +4 Не передан qrcId или payrrn + +5 Не получены данные от СПБ + +8 Таймаут ответа, попробуйте позже + +9 Ошибка идентификации, попробуйте позже + +16 Не передан параметр TermNo + +18 Платеж не найден в запросах B07,B23 <...> + +25 Терминал <номер терминала> заблокирован + +999* Неизвестная ошибка. Необходимо уточнить статус операции. + +Ошибки по методу GetQRCreversalData + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <текст с более подробным описанием ошибки> + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <текст с более подробным описанием ошибки> + +8 Таймаут ответа, попробуйте позже + +12 Не найдены данные для возврата + +16 Не передан параметр TermNo + +20 Получен отказ на запрос возврата. Статус <статус и при наличии код с текстом ошибки> + +21 Не удалось получить получателя перевода + +22 payrrn=<значение payrrn> в запросе не соответствует данным qrcId=<значение qrcId> у которого payrrn=<значение payrrn> + +23 Возврат невозможен для указанных параметров. Для payrrn=<значение payrrn> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +24 Возврат невозможен для указанных параметров. Для qrcId=<значение qrcId> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +25 Терминал <номер терминала> заблокирован + +27 Невозможно выполнить возврат по данному Терминалу, т.к. счёт зачисления не равен счёту списания + +29 Возврат невозможен. Для qrcId=<значение qrcId> не удалось найти успешный ответ на запрос GetQRCstatus + +40 Возврат невозможен. Для payrrn=<значение payrrn> не удалось найти успешный ответ на запрос GetQRCstatus + +1001 Превышено количество повторных запросов возврата B2C + +Ошибки по методу QRCreversal + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <текст с более подробным описанием ошибки> + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 6/8 + +Код Описание + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <текст с более подробным описанием ошибки> + +8 Таймаут ответа, попробуйте позже + +12 Не найдены данные для возврата + +13 Не найден успешный ответ на вызов GetQRCreversalData + +16 Не передан параметр TermNo + +20 Получен отказ на запрос возврата. Статус <статус и при наличии код с текстом ошибки> + +21 Не удалось получить получателя перевода + +22 payrrn=<значение payrrn> в запросе не соответствует данным qrcId=<значение qrcId> у которого payrrn=<значение payrrn> + +23 Возврат невозможен для указанных параметров. Для payrrn=<значение payrrn> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +24 Возврат невозможен для указанных параметров. Для qrcId=<значение qrcId> соответствует trxId=<значение trxId>, а в запросе получен <значение trxId> + +25 Терминал <номер терминала> заблокирован + +27 Невозможно выполнить возврат по данному Терминалу, т.к. счёт зачисления не равен счёту списания + +40 Возврат невозможен. Для payrrn=<значение payrrn> не удалось найти успешный ответ на запрос GetQRCstatus + +201 Получен отказ на запрос возврата. Статус <статус>, недостаточно средств на счёте + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Ошибки по методу ActivateCashQRc + +Код Описание + +-1 Возникли проблемы при обработке запроса: <текст с более подробным описанием ошибки> + +1 Внутренняя ошибка <...> + +2 Терминал <номер терминала> не обнаружен + +3 Не заполнены данные: <...> + +8 Таймаут ответа, попробуйте позже + +16 Не передан параметр TermNo + +25 Терминал <номер терминала> заблокирован + +28 Запрос QR-кода не удался, не был получен Идентификатор QR-кода + +41 При активации кассовой ссылки не удалось получить paramsId + +44 Кассовая ссылка зарегистрирована на устройстве #'<номер терминала>' и может быть использована только на этом устройстве + +301 Некорректно заполнены данные данные: <...> + +999* Неизвестная ошибка. Необходимо уточнить статус операции + +Коды ответов, направляемые в callback-уведомлении по сценарию «Оплата с привязанного счёта» по методу «resolution +/notification» + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 7/8 + +ErrorCode message + +«RQ05031» Отказ Банка Плательщика. Привязка счёта не найдена + +«RQ05032» Отказ Банка Плательщика в проведении платежа + +«RQ05060» Недостаточно денежных средств для проведения операции + +«RQ05061» Превышен лимит по сумме операций по СБП + +«RQ05062» Превышен лимит по количеству операций по СБП + +«RQ05063» Подозрение в мошенничестве + +«RQ05064» Выполнение операций в данной категории ТСП запрещено + +«RQ05065» Счёт заблокирован + +«RQ05066» Счёт закрыт + +«RQ05067» Выполнение операции запрещено по требованию законодательства + +Примечание: Применение кода ответа «RQ05032» допускается не более, чем в 20% от общего числа отказов со стороны Банка +Плательщика при выполнении Сценария «Оплата с привязанного счёта». + +Приложение 3. Пояснение для колонки «required» +«y» — «Yes» обязательное; + +«o» — «Optional» (опционально); + +«y/o» — «Условно обязательное» определяется условиями запроса. + +Приложение 4. Пояснение для колонки «Тип данных» + +Нотация Описание + +a Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8. + +n Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8. + +an Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8; + +Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8. + +ans Символы латинского алфавита (A–Z и a–z) с десятичными кодами из диапазонов [065-090] и [097-122] в кодировке UTF-8; + +Символы русского алфавита (А-Я и а-я) с десятичными кодами из диапазона [1040-1103] в кодировке UTF-8; + +Цифры 0-9 с десятичными кодами из диапазона [048-057] в кодировке UTF-8; + +Специальные символы с десятичными кодами из диапазонов [032-047], [058-064], [091-096], [123-126] в кодировке UTF-8; + +Символ «№» под номером 8470 в кодировке UTF-8. + +12/23/25, 11:25 AM Приложения + +https://alfabank.ru/sme/payservice/sbp/docs/additional/?rp-menuOpen=1 8/8 + + +]]> + +
diff --git a/_docs/xml/saloon_docs.xml b/_docs/xml/saloon_docs.xml new file mode 100644 index 0000000..00a84ea --- /dev/null +++ b/_docs/xml/saloon_docs.xml @@ -0,0 +1,7746 @@ + + + + + + + + +app->singleton(GuzzleSender::class, fn () => new GuzzleSender); + } +} +``` + +Now, inside your Saloon connectors, you should overwrite the `defaultSender` method and resolve the sender which you have bound to the container. + +```php + + + +send(new GetAccessTokenRequest(username: 'Sam', password: 'yee-haw')); +$token = $authResponse->json()['token']; + +$songsRequest = new GetSongsByArtistRequest('Luke Combs'); +$songsRequest->withTokenAuth($token); + +$response = $api->send($songsRequest); +``` + +This is pretty cumbersome. Every time you have to make a request, you have to write all these lines of code. One way you can get around this is by utilizing the `boot` method on your connector. Let's try refactoring this. + +In our connector, we'll extend the `boot()` method which is a method that runs before every request that is sent through that connector, and you get access to the special `PendingRequest` class which is a class that is used to store all the information of a request to be sent in a temporary way. We'll move our logic into here. + +```php +getRequest() instanceof GetAccessTokenRequest) { + return; + } + + // Now let's make our authentication request. Since we are in the + // context of the connector, we can just simply call $this and + // make another request! + + $authResponse = $this->send(new GetAccessTokenRequest($this->username, $this->password)); + + // Now we'll take the token from the auth response and then pass it + // into the $pendingRequest which is the original GetSongsByArtistRequest. + + $pendingRequest->authenticate(new TokenAuthenticator($authResponse->json()['token'])); + } +} +``` + +Now when we send any request using this connector, the authentication will be handled every time! We do have to make sure to pass in our authentication requirements (username, password) into the connector, but this is way better than repeating the same code. Saloon is all about standardisation! + +```php +send(new GetSongsByArtistRequest('Luke Combs')); + +// 200 body: [{name: 'When it rains, it pours'}] +``` + +You may also write additional logic inside of the boot method, like caching access tokens and reusing them. + +]]> + + +- + This page contains a collection of useful start-to-finish guides for doing + specific things in Saloon. +--- + +# 📔 How-to Guides + + +]]> + + + +middleware()->onRequest(function () { + // + }); + + // ✅ Using an invokable class will work + $this->middleware()->onRequest(new MyRequestMiddleware); + + // ✅ Using static will work + $this->middleware()->onRequest(static function () { + // + }); + } +} +``` + +### Minimum TLS Version + +From version three, Saloon uses Guzzle `^7.6` which introduced a new option to configure a minimum TLS version. With Saloon v3, Saloon has set this default to **TLS 1.2.** If any of your API integrations require a lower level of TLS security, you can change the Saloon config while your application is loading. + +```php +use Saloon\Config; + +Config::$defaultTlsMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; +``` + +You can [visit this page on the PHP documentation](https://www.php.net/manual/en/function.stream-socket-enable-crypto.php) to see the different TLS options available. + +{% hint style="info" %} +**TLS 1.1** has been deprecated since 2021 so it is unlikely that APIs are still using it, but older systems may have not upgraded yet. +{% endhint %} + +]]> + + +
+ +We're super excited to partner with [Ash Allen](https://twitter.com/AshAllenDesign) with his latest book - _Consuming APIs in Laravel**.**_ This book with over 440 pages contains everything you need to build awesome API integrations in Laravel. The book uses Saloon as the tool to build the integrations, so it's a great way to learn Saloon inside out too! + +You'll also learn about the most common types of APIs, How OAuth2 works and how to handle webhooks securely. + +{% hint style="info" %} +Use code **SALOON** at checkout to get **20% off** the "Consuming APIs in Laravel" book or the book bundle with "Battle Ready Laravel"! +{% endhint %} + +[Pick up your copy today at consuming-apis-in-laravel.com!](https://consuming-apis-in-laravel.com/?aff=DGMrX) + +]]> +
+ + + + + + + + + + + + + + + 🚨 + ohdearapp/ohdear-php-sdk + 1 + + + https://github.com/ohdearapp/ohdear-php-sdk + + + 🌲 + astrotomic/ecologi-sdk + 1 + + + https://github.com/Astrotomic/ecologi-sdk + + + 🪐 + astrotomic/tmdb-sdk + 2 + + + https://github.com/Astrotomic/tmdb-sdk + + + 💰 + myoutdeskllc/salesforce-php + 3 + + + https://github.com/MyOutDeskLLC/SalesforcePhp + + + 🤑 + sawirricardo/midtrans-api + + + + https://github.com/sawirricardo/midtrans-api + + + 📃 + carboneio/carbone-sdk-php + + + + https://github.com/carboneio/carbone-sdk-php + + + 📞 + samuelmwangiw/africastalking-laravel + + + + https://github.com/SamuelMwangiW/africastalking-laravel + + + 💻 + samuelmwangiw/linode + + + + https://github.com/SamuelMwangiW/linode + + + 🌱 + alphaolomi/json-placeholder + + + + https://github.com/alphaolomi/json-placeholder + + + 💬 + flourishlabs/saloon-slack + + + + https://github.com/flourishlabs/saloon-slack + + + 📦 + alphaolomi/laravel-repman + + + + https://github.com/alphaolomi/laravel-repman + + + 📊 + njoguamos/laravel-plausible + + + + https://github.com/njoguamos/laravel-plausible + + + 🧠 + probots-io/pinecone-php + + + + https://github.com/probots-io/pinecone-php + + + 🇨🇴 + felipeva/api-colombia-php + + + + https://github.com/felipeva/api-colombia-php + + + 🤝 + deschutesdesigngroupllc/perscom-php-sdk + + + + https://github.com/DeschutesDesignGroupLLC/perscom-php-sdk + + + ✈️ + noahnxt/laravel-open-holiday-api + + + + https://github.com/NoahNxT/laravel-open-holidays-api + + + 💰 + njoguamos/laravel-pesapal + + + + https://github.com/njoguamos/laravel-pesapal + + + 🔖 + oneduo/github-sdk-php + + + + https://github.com/oneduo/github-sdk-php + + + 💳 + lloricode/paymaya-sdk-php + + + + https://github.com/lloricode/paymaya-sdk-php + + + + +]]> + + + + +
+ + +send(new GetUserRequest); + } +}; + +// ⬇️ Takes 2.5 seconds! 🔥 + +$requests = function () { + for ($i = 0; $i < 1000; $i++) { + yield new GetUserRequest; + } +}; + +$connector->pool($requests, concurrency: 10)->send()->wait(); +``` + +### Getting Started + +Saloon's pooling has been designed specifically to be easy to use. Simply instantiate your connector class and use the `pool` method to create a pool. This method doesn't require any arguments, but you may provide requests, concurrency and handlers right from this method. + +```php +pool( + requests: [], + concurrency: 5, + responseHandler: function () { ... }, + exceptionHandler: function () { ... }, +); + +// Initiate the transfer of requests + +$promise = $pool->send(); + +// Force all the requests to be fulfilled + +$promise->wait(); +``` + +### Available Methods + +* `setRequests(callable|iterable $requests)` +* `getRequests()` +* `withResponseHandler(callable $callable)` +* `withExceptionHandler(callable $callable)` +* `send()` + +### Providing Requests + +The pool class accepts many types of requests: + +* Array of requests +* PHP generator providing requests +* Closure or Invokable class returning an array of requests +* Closure or Invokable class returning a generator + +You may provide these requests into the pool either as the first argument of the `pool` method or using the `setRequests` method. The requests can be instances of `Saloon\Http\Request` or `Saloon\Http\PendingRequest`. + +#### Array of requests + +The simplest way to provide requests to the pool is an array. + +```php +pool([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); + +// Or + +$pool = $forge->pool(); + +$pool->setRequests([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); +``` + +#### Using a PHP generator + +If you are going to send lots of requests you may wish to provide a generator into the pool. This allows you to keep memory consumption low and potentially send hundreds of requests. + +```php + new UserRequest; + } +}; + +$forge = new ForgeConnector; +$pool = $forge->pool($generatorCallback); + +// or + +$pool->setRequests($generatorCallback); +``` + +#### Using a callable or invokable class + +You may wish to use a callable method to return an array of requests or a generator, this is useful if you have any additional logic that needs to execute just before the request pool begins. + +{% tabs %} +{% tab title="Callable" %} +```php +pool($callback); + +// or + +$pool->setRequests($callback); +``` +{% endtab %} + +{% tab title="Invokable Class" %} +```php +pool(new PoolClass); +``` +{% endtab %} +{% endtabs %} + +### Concurrency + +By default, Saloon will send up to 5 requests concurrently. You can customise the concurrency that is used by pools with the `setConcurrency` method. It accepts an integer or a callable like a method or an invokable class in case you want to write advanced logic to determine the concurrency. + +```php +pool(...); + +$pool->setConcurrency(10); + +// or + +$pool->setConcurrency(function () { + return 10; +}); +``` + +### Response Handlers + +When you send requests with pooling, each request is asynchronous, so you cannot guarantee when they are returned. In order to handle the response, Saloon has provided you with two handlers to handle successful requests and failed requests. + +#### Handling Successful Requests + +Any responses that are successful will be handled by the response handler. You may add this with the constructor of your pool or add it once it is created. You can only have one handler. You will get a response instance. + +```php +pool( + requests: [], + concurrency: 5, + responseHandler: function (Response $response) { + // Handle Response + }, +); + +// Or + +$pool->withResponseHandler(function (Response $response) { + // Handle Response +}); +``` + +#### Handling Failed Requests + +When requests fail, they will always be caught with the error handler, even if you don't throw on requests. When a failed request happens you can handle the exception with the `withExceptionHandler` method. + +```php +pool( + requests: [], + concurrency: 5, + exceptionHandler: function (FatalRequestException|RequestException $exception) { + // Handle Exception + }, +); + +// Or + +$pool->withExceptionHandler(function (FatalRequestException|RequestException $exception) { + // Handle Exception +}); +``` + +### Named/Keyed Requests + +Saloon also supports keyed responses to help you easily track exact requests that have been sent. This is especially useful if you are sending requests to different endpoints. You may use keying with arrays or even with a generator. + +```php +pool([ + 'servers' => new GetServersRequest, + 'sites' => new GetSitesRequest, + 'user' => new GetUserRequest, +]); + +// You may access the key in the response and error handlers + +$pool->withResponseHandler(function (Response $response, string $key) { + match($key) { + 'servers' => $this->updateServersList($response), + 'sites' => $this->updateSitesList($response), + 'user' => $this->updateUser($response), + } +}); +``` + +### Sending + +Once you have provided the pool with requests, you are ready to send them. Just use the `send` method on the pool. This will return an instance of `PromiseInterface` . Requests will be handled asynchronously but you can force them to complete with the `wait` method. + +```php +pool([ + new GetServersRequest, + new GetSitesRequest, + new GetUserRequest, +]); + +$pool->withResponseHandler(function (Response $response) { + // Handle Response +}); + +$pool->withExceptionHandler(function (FatalRequestException|RequestException $exception) { + // Handle Exception +}); + +// Initiate the transfer of requests + +$promise = $pool->send(); + +// Force all the requests to be fulfilled + +$promise->wait(); +``` + +]]> + + +delay()->set(500); +``` +{% endtab %} + +{% tab title="Request" %} +```php +delay()->set(500); +``` +{% endtab %} +{% endtabs %} + +{% hint style="warning" %} +If you have defined the delay on both the connector and the request, the request delay will take priority. +{% endhint %} + +]]> + + +headers()->add('X-Current-Time', new DateTime); + } +} +``` +{% endtab %} + +{% tab title="Request" %} +```php +headers()->add('X-Current-Time', new DateTime); + } +} +``` +{% endtab %} +{% endtabs %} + +### The PendingRequest + +The `PendingRequest` class is an intermediary class that Saloon uses to populate everything when you send a request. Every time you send a request, a new `PendingRequest` instance is created which prevents your connector or request from being mutated every time a request is sent. The `PendingRequest` class has many of the methods that you are used to seeing on the request/connector for managing headers, query parameters, config, and request body. + +The `PendingRequest` class is used for boot methods, middleware and [plugins](../installable-plugins/traits.md). + +### Request Middleware + +You may also at any point tap into the request lifecycle by using request middleware. Request middleware is useful for changing something on the `PendingRequest` instance before the request is sent like making another request to get an authentication token for the original request. + +On your connector or request, call the `middleware()` method and use the `onRequest()` method. You should provide a callable, like a closure or invokable class. This callable will be given access to the `PendingRequest` instance which can be mutated. + +{% hint style="info" %} +Return values are not required, but you may either return an instance of `PendingRequest` or a `FakeResponse` class for an early fake response. +{% endhint %} + +#### Anonymous Functions + +You can use a regular closure/anonymous function to create a middleware on the fly. + +{% tabs %} +{% tab title="Connector" %} +```php +middleware()->onRequest(function (PendingRequest $pendingRequest) { + $pendingRequest->headers()->add('Authorization', 'Bearer ' . $token); +}); +``` +{% endtab %} + +{% tab title="Request" %} +```php +middleware()->onRequest(function (PendingRequest $pendingRequest) { + $pendingRequest->headers()->add('Authorization', 'Bearer ' . $token); +}); +``` +{% endtab %} +{% endtabs %} + +#### Invokable Classes + +You may also use invokable classes to keep your middleware classes tidy. If you are using invokable middleware classes, you should implement the `RequestMiddleware` interface. + +{% tabs %} +{% tab title="Definition" %} +```php +headers()->add('Authorization', 'Bearer ' . $token); + } +} +``` +{% endtab %} + +{% tab title="Usage (Connector)" %} +```php +middleware()->onRequest(new AuthenticateRequest); +``` +{% endtab %} + +{% tab title="Usage (Request)" %} +```php +middleware()->onRequest(new AuthenticateRequest); +``` +{% endtab %} +{% endtabs %} + +### Early Fake Responses + +You may also choose to tap into Saloon's mock functionality by creating your own fake responses. When you return a `FakeResponse`, the rest of the request middleware will still be processed but the fake response will be stored on the `PendingRequest`. + +If this fake response is present before Saloon sends the request, it won't send the request to the sender, instead, Saloon will use the `FakeResponse`. This is super handy if you want to build your own middleware that stops Saloon from sending real requests, like for caching. + +```php +middleware() + ->onRequest(function (PendingRequest $pendingRequest) { + return new FakeResponse( + body: ['data' => 'Fake Data!'], + status: 200, + headers: [] + ); + }); +``` + +{% hint style="warning" %} +Even though you are returning a `FakeResponse` class, the next middleware will still receive the PendingRequest instance. Additionally, if another middleware also returns a fake response, the latest one will be used. +{% endhint %} + +### Response Middleware + +Once you have sent your request, even if it's a fake response, Saloon will send the response down the response middleware pipeline. You may add your own response middleware to change the response class or do something like log responses. + +On your connector or request, you can call the `middleware()` method and use the `onResponse()` method. You should provide a callable, like a closure or invokable class. This callable will be given access to the `Response` instance. + +{% hint style="info" %} +Return values are not required, but you may return an instance of `Saloon\Http\Response` to overwrite the response class in the middleware. +{% endhint %} + +#### Anonymous Functions + +You can use a regular closure/anonymous function to create a middleware on the fly. + +{% tabs %} +{% tab title="Connector" %} +```php +middleware()->onResponse(function (Response $response) { + Logger::recordResponse($response); +}); +``` +{% endtab %} + +{% tab title="Request" %} +```php +middleware()->onResponse(function (Response $response) { + Logger::recordResponse($response); +}); +``` +{% endtab %} +{% endtabs %} + +#### Invokable classes + +Similar to request middleware, you can also create invokable middleware classes for response middleware. You should use the `ResponseMiddleware` contract to ensure your invokable class has the correct signature. + +{% tabs %} +{% tab title="Definition" %} +```php +middleware()->onResponse(new LogResponse); +``` +{% endtab %} + +{% tab title="Usage (Request)" %} +```php +middleware()->onResponse(new LogResponse); +``` +{% endtab %} +{% endtabs %} + +### Using Constructors + +While registering middleware on the fly is really useful, it often leads to repeated code. If you would like your connector to always have a specific request or response middleware you should use the `boot` method described above, or use the constructor of your connector or request. + +```php +middleware()->onRequest(new AuthenticateRequest); + $this->middleware()->onResponse(new LogResponse); + } +} +``` + +{% hint style="danger" %} +Be cautious using anonymous non-static closures inside the constructor/boot method. This may cause issues like Saloon not being able to close connections properly. [Click here to read more.](../conclusion/known-issues.md#usage-of-anonymous-functions-with-long-running-processes-like-laravel-queues) +{% endhint %} + +### Using Plugins + +Plugins are another useful feature for Saloon that allows you to extend Saloon and tap into the middleware from traits. This is especially useful if you intend to use the trait on multiple requests or connectors. + +[Read through the plugins page for more information.](../installable-plugins/traits.md) + +### Middleware Naming + +You can choose to name your middleware. Each name must be unique to the given pipeline. For example, you cannot have two middleware with the same name on the request pipeline, but you could have the same name used once for the request pipeline and once for the response pipeline. Use the second argument to specify a name. + +```php +middleware()->onResponse(new LogResponse, 'logResponse'); +``` + +### Global Middleware + +Saloon also supports adding global middleware. You most likely won't need this level of granularity but if you do, you may use the `Config` class. When using global middleware, you should make sure to name your middleware so it isn't accidentally registered twice. + +```php +onResponse(new LogResponse, 'logResponse'); +``` + +{% hint style="danger" %} +Be cautious with global middleware. Since it uses a static property behind the scenes, the value is kept between tests when running a full test suite. You can use the `Config::clearGlobalMiddleware()` method to get around this issue. +{% endhint %} + +### Middleware Execution Order + +The following is the order in which middleware is executed. + +1. Global middleware (Like the Laravel plugin) +2. Mock client finds a fake response (if present) +3. Plugin middleware +4. User-added middleware +5. Debugging middleware is run (for the final object) + +### Choosing When Your Middleware Is Executed + +You may choose to change when your middleware is executed. For example, you might want to run something at the very end of all the other middleware that has been run. This is especially useful if you are building a plugin for people to install in Saloon and require the final request object before it is sent. You can use the third argument to specify an order. This expects a `PipeOrder` enum and allows you to choose either `FIRST` or `LAST`. + +When the middleware is executed, any middleware marked as "first" will run first, and any that have been marked as "last" will be executed last. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\PendingRequest;
+use Saloon\Enums\PipeOrder;
+
+class GetServersRequest extends Request
+{
+    // { ... }
+    
+    public function boot(PendingRequest $pendingRequest): void
+    {
+        $request->middleware()->onRequest(new RecordResponse, order: PipeOrder::LAST);
+    }
+}
+
+ +### Middleware Caveats + +Here are some known caveats that you should know about when using Saloon's middleware. + +* You cannot add request middleware from inside of another request middleware**,** but you can add response middleware inside of the onRequest() middleware method. +* You cannot add response middleware from inside of another response middleware. +* You may return a fake response in request middleware but you will always get a PendingRequest back + +### Guzzle Handlers / Middleware + +With previous versions of Saloon, you could add Guzzle middleware or "handlers" directly to the connector or request. From version two, Saloon is now sender-agnostic, so the `addHandler` method has been removed but you may still add Guzzle middleware if you are using the `GuzzleSender` (the default sender with Saloon) + +### Adding Guzzle Middleware + +You can add middleware to the Guzzle client by using the `sender` method on the connector. You must only add Guzzle middleware directly on your connector with your constructor method. This is because Saloon only instantiates the sender once, so in order to prevent middleware from being registered multiple times, it should be placed in the constructor. + +```php +sender()->addMiddleware(function (callable $handler) { + return function (RequestInterface $request, array $options) use ($handler) { + $request->withHeader('X-Custom-Header', 'Hello'); + + return $handler($request, $options); + }; + }) + } +} +``` + +{% hint style="info" %} +To read more about Guzzle's middleware and handlers [click here](https://docs.guzzlephp.org/en/stable/handlers-and-middleware.html). +{% endhint %} + +### Accessing The Underlying Guzzle Instance + +You may need to modify the Guzzle client or the handler stack. If you need to do this, you can use the `getGuzzleClient` or `getHandlerStack` methods. + +```php +sender()->getGuzzleClient(); + + $handlerStack = $this->sender()->getHandlerStack(); + } +} +``` + +]]> +
+ + +getAccessToken($scopes); + +// 2. Authenticate the connector + +$connector->authenticate($authenticator); + +// 3. Send your requests + +$connector->send(new GetInventoryRequest); +``` + +### Getting Started + +Let's start with preparing our connector to support the client credentials grant. All we have to do is add the `ClientCredentialsGrant` trait to our connector. + +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setDefaultScopes(['inventory.read']) + ->setTokenEndpoint('/oauth/token') + ->setRequestModifier(function (Request $request) { + // Optional: Modify the requests being sent. + }); + } +} +``` + +{% hint style="info" %} +The endpoint method, like `setTokenEndpoint` on the OAuthConfig class supports full URLs if you need to overwrite the base URL on the connector however you may just use the endpoint if the base URL is the same. +{% endhint %} + +#### Overwriting the OAuth2 config + +Sometimes, you may have a different OAuth2 client ID and secret for each user of your application. If your OAuth2 config is dependent on a per-user/tenant basis, it's recommended that you pass in the credentials as constructor arguments of your connector and then set the `oauthConfig` inside the constructor. + +In the following example, I will pass in the `$clientId` and the `$clientSecret` as constructor arguments and overwrite the OAuth2 config. + +```php +oauthConfig()->setClientId($clientId); + $this->oauthConfig()->setClientSecret($clientSecret); + } + + // ... +} +``` + +### Creating Access Tokens + +You are now ready to create access tokens. You should use the `getAccessToken` method on your connector. If successful, the method will return an `AccessTokenAuthenticator`. The access token and expiry (if provided) are wrapped up in a [Saloon Authenticator](../../the-basics/authentication.md#custom-authenticators) class that can be used to authenticate your connector/requests. It acts like a DTO that can be easily serialized and transported around your application. + +```php +getAccessToken(); + +// Use authenticator to authenticate your connector instance + +$connector->authenticate($authenticator); + +// Any request sent through this connector will now have authentication applied + +$connector->send(new GetInventoryRequest); +``` + +{% hint style="info" %} +Once you have received the authenticator instance, you should cache it securely in your application for future use. Read further to see how you can do this. +{% endhint %} + +#### Custom Scopes + +Sometimes you may need to provide an additional "scope" to declare the level of access that your token needs. You may provide default scopes in the OauthConfig class on your connector, but you can also provide additional scopes when creating access tokens. Saloon will separate scopes with spaces but if your API integration requires scopes to be separated any other way, you can specify this with the `scopeSeparator` argument. + +```php +getAccessToken( + scopes: ['inventory.update', 'inventory.delete'], + scopeSeparator: '+', +); +``` + +#### Returning Responses + +If you prefer, you may request Saloon to return a `Saloon\Http\Resonse` instance instead of a `AccessTokenAuthenticator` when creating access tokens. To use responses, just provide the `returnResponse` argument when creating access tokens. + +```php +getAccessToken( + returnResponse: true, +); +``` + +### Authenticator Methods + +The authenticator returned by Saloon when using the `getAccessToken` method will contain the Access Token, and optionally an expiry date that was returned by the OAuth2 server. You can access these properties with the following methods. You can also check if the authenticator has expired, which will come in handy when refreshing access tokens. + +```php +getAccessToken(); +$authenticator->getExpiresAt(); + +$authenticator->hasExpired(); +$authenticator->hasNotExpired(); +``` + +### Customising The Authenticator + +Sometimes the API provider you are authenticating with may require additional information to be used in the authenticator. You can customise how the authenticator will be created by extending the `createAccessTokenAuthenticator` method on your connector. + +```php +object(); + + $accessToken = $responseData->access_token; + $expiresAt = new DateTimeImmutable('+' . $responseData->expires_in . ' seconds'); + + return $this->createOAuthAuthenticator($accessToken, $expiresAt); +} +``` + +### Customising The Requests + +Sometimes you might integrate with an API that requires additional query parameters or headers to be sent with the OAuth2 flow. You may use the `requestModifier` method on the `getAccessToken` method or use the `setRequestModifier` method within the `OAuthConfig` to add a callable that is invoked before a request is sent. + +{% tabs %} +{% tab title="Per Request" %} +```php +getAccessToken(requestModifier: function (Request $request) { + $request->query()->add('access_type', 'offline'); +}); +``` +{% endtab %} + +{% tab title="All Requests" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\OAuth2\GetClientCredentialsTokenRequest;
+
+protected function defaultOauthConfig(): OAuthConfig
+{
+    return OAuthConfig::make()
+        ->setClientId('my-client-id')
+        ->setClientSecret('my-client-secret')
+        ->setRequestModifier(function (GetClientCredentialsTokenRequest $request) {
+            //
+        }),
+}
+
+{% endtab %} +{% endtabs %} + +### Using your own request classes + +There are situations where Saloon's own request classes for getting the access token might not suit the API you are integrating with. For example, if an API uses JSON encoding instead of form encoding. You may use the following method on your connector to overwrite the instantiation process of the request class. + +```php + +
+ +getAuthorizationUrl($scopes, $state); + +// 2. Handle the callback from the API provider and create an access token... + +$authenticator = $connector->getAccessToken($code, $state); + +// 3. Authenticate the connector + +$connector->authenticate($authenticator); + +// 4. Send your requests + +$connector->send(new GetTracksRequest); + +// 5. Refresh your access tokens... + +$newAuthenticator = $connector->refreshAccessToken($authenticator); +``` + +### Getting Started + +Let’s start with preparing our connector to support the Authorization Code Flow. All we have to do is add the `AuthorizationCodeGrant` trait to our connector. + +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setDefaultScopes(['user-read-currently-playing']) + ->setRedirectUri('https://my-app.saloon.dev/auth/callback') + ->setAuthorizeEndpoint('https://accounts.spotify.com/authorize') + ->setTokenEndpoint('https://accounts.spotify.com/api/token') + ->setUserEndpoint('/me') + ->setRequestModifier(function (Request $request) { + // Optional: Modify the requests being sent. + }); + } +} +``` + +{% hint style="info" %} +Each of the endpoint methods, like `setAuthorizeEndpoint`on the OAuthConfig class support full URLs if you need to overwrite the base URL on the connector however you may just use the endpoint if the base URL is the same. +{% endhint %} + +#### Overwriting the OAuth2 config + +Sometimes, you may have a different OAuth2 client ID and secret for each user of your application. If your OAuth2 config is dependent on a per-user/tenant basis, it's recommended that you pass in the credentials as constructor arguments of your connector and then set the `oauthConfig` inside the constructor. + +In the following example, I will pass in the `$clientId` and the `$clientSecret` as constructor arguments and overwrite the OAuth2 config. + +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\Traits\OAuth2\AuthorizationCodeGrant;
+
+class SpotifyConnector extends Connector
+{
+    use AuthorizationCodeGrant;
+
+    public function __construct(string $clientId, string $clientSecret)
+    {
+        $this->oauthConfig()->setClientId($clientId);
+        $this->oauthConfig()->setClientSecret($clientSecret);
+    }
+
+    // ...
+}
+
+ +### Creating an Authorization URL + +Now we have setup our connector to support the authorization code grant, we are ready to start the OAuth2 process. Usually, the first stage is to generate a URL to redirect our application users to. To generate an authorization URL, you can use the `getAuthorizationUrl` method on the connector. + +```php +getAuthorizationUrl(); +``` + +You can also pass in scopes which will be merged with the default scopes if you provided them in the OAuth config. Saloon will separate scopes with spaces but if your API integration requires scopes to be separated any other way, you can specify this with the `scopeSeparator` argument. + +```php +$authorizationUrl = $connector->getAuthorizationUrl( + scopes: ['user-library-read'], + scopeSeparator: '+', +); +``` + +You can also provide additional query parameters if you need to with the `additionalQueryParameters` argument. This should be a key-value array where the key is the query parameter name and the value is the value of the query parameter. + +```php +$authorizationUrl = $authConnector->getAuthorizationUrl( + additionalQueryParameters: [ + 'username' => 'JohnWayne' + ], +); +``` + +#### State + +To help prevent CSRF attacks or send additional data during authentication, you can pass an additional unique string in your authorization URL that the API's OAuth2 server will send back to you after your user has approved or denied access to your OAuth2 app. + +```php +$authorizationUrl = $authConnector->getAuthorizationUrl( + state: 'application-user-id', +); +``` + +If you do not provide your own state, Saloon will automatically generate a unique, 32-character string. Once you have generated the authorization URL, you can then use the `getState` method on your connector to get the state back. You should store this string in your application's session or cache to be verified later. + +
<?php
+
+$connector = new SpotifyConnector;
+$authorizationUrl = $connector->getAuthorizationUrl();
+
+$state = $authConnector->getState(); // '8484b43fdjfdnfdj3llls...'
+
+ +### Creating Access Tokens + +After the user has approved your application, the API provider will redirect you back to your application with an authorization code and state. This data usually sent in the form of query parameters should be passed into your `getAccessToken` method on your connector. If successful, the method will return an `AccessTokenAuthenticator`. The access token, refresh token and expiry are wrapped up in a [Saloon Authenticator](../../the-basics/authentication.md#custom-authenticators) class that can be used to authenticate your connector/requests. It acts like a DTO that can be easily serialized and transported around your application. + +
<?php
+
+$connector = new SpotifyConnector;
+$authenticator = $authConnector->getAccessToken($code);
+
+// Use authenticator to authenticate your connector instance
+
+$connector->authenticate($authenticator);
+
+// Any request sent through this connector will now have authentication applied
+
+$connector->send(new GetTracksRequest);
+
+ +{% hint style="info" %} +Once you have received the authenticator instance, you should cache it securely in your application for future use. Read further to see how you can do this. +{% endhint %} + +#### Verifying State + +If you stored the state that was generated during creating an authorization URL, you should pass this expected state alongside the state sent back by the API provider's OAuth2 server. This will be used to verify the state provided back by the application is valid. If the state does not match the expected state, Saloon will throw an exception. + +```php +getAccessToken($code, $state, $expectedState); +``` + +### Storing Authentication For Later + +You will likely need to store the authenticator securely so you can use it for future requests. You may serialize and unserialize the authenticator class using the helper methods below, then you can store the string wherever you like, usually encrypted in the database if it's against a user. Then, you can retrieve this authenticator and use it to authenticate your connector. + +```php +getAccessToken($code); + +// Securely store this against your user. + +$serialized = $authenticator->serialize(); + +// Unserialize the authenticator when retrieving it + +$authenticator = AccessTokenAuthenticator::unserialize($serialized); +``` + +### Authenticator Methods + +The authenticator returned by Saloon when using the `getAccessToken` or `refreshAccessToken` methods will contain the Access Token, Refresh Token and Expiry Date that was returned by the OAuth2 server. You can access these properties with the following methods. You can also check if the authenticator has expired, which will come in handy when refreshing access tokens. + +```php +getAccessToken(); +$authenticator->getRefreshToken(); +$authenticator->getExpiresAt(); + +$authenticator->hasExpired(); +$authenticator->hasNotExpired(); +``` + +### Refreshing Access Tokens + +When retrieving your authenticator out of storage, you should always check if the access token has expired and if it needs refreshing. If the authenticator's access token has expired, you can call the `refreshAccessToken` method which will create a fresh authenticator. + +In this example, `$user` is the user of my application and I have written methods to get and store the authenticators. + +```php +getCachedAuthenticator(); +$connector = new SpotifyConnector; + +if ($authenticator->hasExpired()) { + // We'll refresh the access token which will return a new authenticator + // which we can store against our user in our application. + + $authenticator = $connector->refreshAccessToken($authenticator); + $user->updateAuthenticator($authenticator); +} + +// Authenticate our connector and send the request + +$connector->authenticate($authenticator); + +$response = $connector->send(new GetTracksRequest); +``` + +{% hint style="info" %} +If you are using Laravel and the Saloon Laravel library, you can use built-in `EncryptedOAuthAuthenticatorCast` **/** `OAuthAuthenticatorCast` Eloquent casts to automatically cast the authenticator for storing in your database. +{% endhint %} + +### Customising The Authenticator + +Sometimes the API provider you are authenticating with may require additional information to be used in the authenticator. You can customise how the authenticator will be created by extending the `createAccessTokenAuthenticator` method on your connector. + +```php +object(); + + $accessToken = $responseData->access_token; + $refreshToken = $responseData->refresh_token ?? $fallbackRefreshToken; + $expiresAt = new DateTimeImmutable('+' . $responseData->expires_in . ' seconds'); + + return $this->createOAuthAuthenticator($accessToken, $refreshToken, $expiresAt); +} +``` + +### Customising The Requests + +Sometimes you might integrate with an API that requires additional query parameters or headers to be sent with the OAuth2 flow. You may use the `requestModifier` property on the methods or use the `setRequestModifier` method within the `OAuthConfig` to add a callable that is invoked before a request is sent. + +{% tabs %} +{% tab title="Per Request" %} +```php +getAccessToken($code, requestModifier: function (Request $request) { + $request->query()->add('access_type', 'offline'); +}); + +$connector->getRefreshToken($code, requestModifier: function (Request $request) { + $request->headers()->add('X-App-Key', $appKey); +}); + +$connector->getUser($code, requestModifier: function (Request $request) { + $request->headers('Accept', 'text/plain'); +}); +``` +{% endtab %} + +{% tab title="All Requests" %} +```php +setClientId('my-client-id') + ->setClientSecret('my-client-secret') + ->setRedirectUri('https://my-app.saloon.dev/auth/callback') + ->setRequestModifier(function (Request $request) { + // This callback is invoked on every request, so you + // may want to use if-statements or a match statement + // to apply conditions based on request. + + if ($request instanceof GetAccessTokenRequest) { + $request->query()->add('access_type', 'offline'); + } + + if ($request instanceof GetRefreshTokenRequest) { + $request->headers()->add('X-App-Key', $appKey); + } + + if ($request instanceof GetUserRequest) { + $request->headers('Accept', 'text/plain'); + } + }), +} +``` +{% endtab %} +{% endtabs %} + +### Using your own request classes + +There are situations where Saloon's own request classes for getting the access token, refreshing the access token or getting the user might not suit the API you are integrating with. For example, if an API uses JSON encoding instead of form encoding. You may use the following methods on your connector to overwrite the instantiation process of the request classes. + +```php +getAccessToken( + returnResponse: true, +); + +$response = $connector->refreshAccessToken( + returnResponse: true, +); +``` + +### Real-world example + +If you would like to see an example integration using the OAuth2 methods mentioned above, you can see the following Laravel application. + +[https://github.com/Sammyjo20/saloon-v2-spotify-example](https://github.com/Sammyjo20/saloon-v2-spotify-example) + +]]> +
+ + + +
+ + +<?php + +use Saloon\Http\Response; +use Saloon\Http\Connector; +use Saloon\PaginationPlugin\CursorPaginator; +use Saloon\PaginationPlugin\Contracts\HasPagination; + +class SpotifyConnector extends Connector implements HasPagination +{ + // ... + + public function paginate(Request $request): CursorPaginator + { + return new class(connector: $this, request: $request) extends CursorPaginator + { + // + }; + } +} + + +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define three protected methods which are used to power the paginator. These methods are: + +* **getNextCursor** - This method is used to find the next cursor from the response. This method must return either an integer or a string. The next cursor is used in the next request to get a different page. +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement these three methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\CursorPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): CursorPaginator
+    {
+        return new class(connector: $this, request: $request) extends CursorPaginator
+        {
+            protected function getNextCursor(Response $response): int|string
+            {
+                return $response->json('next_cursor');
+            }
+        
+            protected function isLastPage(Response $response): bool
+            {
+                return is_null($response->json('next_cursor'));
+            }
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+        };
+    }
+}
+
+ +Let's assume in this hypothetical example that the API provides a `next_cursor` property in the JSON response. We'll return the value of this property in the `getNextCursor` method. After that, we need to tell Saloon when to stop paginating. We'll use the same `next_cursor` property again. If it's null, we know that there isn't another page to look up. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): CursorPaginator
+{
+    return new class(connector: $this, request: $request) extends CursorPaginator
+    {
+        protected ?int $perPageLimit = 100;
+        
+        // ...
+    }
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the CursorPaginator** + +The CursorPaginator will apply pagination by sending two **query parameters**: + +* cursor +* per\_page + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects a "pageCursor" and a "pageSize" instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): CursorPaginator
+{
+    return new class(connector: $this, request: $request) extends CursorPaginator
+    {
+        protected function getNextCursor(Response $response): int|string
+        {
+            return $response->json('next_cursor');
+        }
+    
+        protected function isLastPage(Response $response): bool
+        {
+            return is_null($response->json('next_cursor'));
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            if ($this->currentResponse instanceof Response) {
+                $request->query()->add('pageCursor', $this->getNextCursor($this->currentResponse));
+            }
+    
+            if (isset($this->perPageLimit)) {
+                $request->query()->add('pageSize', $this->perPageLimit);
+            }
+    
+            return $request;
+        }
+    };
+}
+
+ +### **Useful Properties On The CursorPaginator** + +We previously mentioned that the CursorPaginator class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **page** - An integer which will return the current page that the paginator is currently on. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. + +]]> +
+ +<?php + +use Saloon\Http\Response; +use Saloon\Http\Connector; +use Saloon\PaginationPlugin\Paginator; +use Saloon\PaginationPlugin\Contracts\HasPagination; + +class SpotifyConnector extends Connector implements HasPagination +{ + // ... + + public function paginate(Request $request): Paginator + { + return new class(connector: $this, request: $request) extends Paginator + { + // + }; + } +} + + +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define three protected methods which are used to power the paginator. These methods are: + +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. +* **applyPagination** - This method is used to change each request to apply the pagination for the next page. + +Let's implement these three methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\Paginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+
+    public function paginate(Request $request): Paginator
+    {
+        return new class(connector: $this, request: $request) extends Paginator
+        {
+            protected function isLastPage(Response $response): bool
+            {
+                return is_null($response->json('next_page_url'));
+            }
+
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+
+            protected function applyPagination(Request $request): Request
+            {
+                $request->headers()->add('X-Page', $this->currentPage);
+
+                $request->headers()->add('X-Per-Page', $this->perPageLimit);
+
+                return $request;
+            }
+        };
+    }
+}
+
+ +Let's assume in this hypothetical example that the API provides some useful information to see if we're on the last page. In this example, we know we're on the last page if the `next_page_url` JSON property on the body is null. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +After that, to apply the pagination, our API expects us to send a `X-Page` header with the current page on the paginator. We'll use the `$this->currentPage` property on the paginator as it acts like an index for the current iteration of the paginator. We will also make sure to send the `perPageLimit` to our API with the `X-Per-Page` header. This header is optional depending on the third-party API you are integrating with. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): Paginator
+{
+    return new class(connector: $this, request: $request) extends Paginator
+    {
+        protected ?int $perPageLimit = 100;
+
+        // ...
+    };
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +{% hint style="warning" %} +For this feature to work, you must implement sending the `perPageLimit` inside of your `applyPagination` method in whichever way your API may expect. +{% endhint %} + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. + +]]> +
+ +<?php + +use Saloon\Http\Response; +use Saloon\Http\Connector; +use Saloon\PaginationPlugin\OffsetPaginator; +use Saloon\PaginationPlugin\Contracts\HasPagination; + +class SpotifyConnector extends Connector implements HasPagination +{ + // ... + + public function paginate(Request $request): OffsetPaginator + { + return new class(connector: $this, request: $request) extends OffsetPaginator + { + // + }; + } +} + + +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define a single property and two protected methods which are used to power the paginator. These properties/methods are: + +* **perPageLimit** - This property is required as this is the default limit of the paginator. Since this paginator requires limit/offset - the limit is always required. If you need to change the limit on a per-request basis you can change it on the paginator instance. +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here, you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next-page URLs, which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement the property and the two methods on our paginator and dive into how it works. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\OffsetPaginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): OffsetPaginator
+    {
+        return new class(connector: $this, request: $request) extends OffsetPaginator
+        {
+            protected ?int $perPageLimit = 100;
+        
+            protected function isLastPage(Response $response): bool
+            {
+                return $this->getOffset() >= (int)$response->json('total');
+            }
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->json('items');
+            }
+        };
+    }
+}
+
+ +First, we'll define a `perPageLimit` of 100. This means that every request will attempt to use a "limit" of 100. + +Next, let's assume in this hypothetical example that the API provides some useful information that helps us calculate if we're on the last page. For example, our API returns a `total` integer with every page - this number is simply the total results across all pages. We can use this to compare it with the current offset, and if the offset is greater than or equal to the total, we will stop. There are other ways of knowing if you are on the last page, so it's best to understand your API's pagination fully. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Changing the per-page limit on the paginator + +As mentioned previously, you must specify a "per-page limit" on your offset paginator. You may also use the `setPerPageLimit` method on an instantiated paginator if you want to change it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the OffsetPaginator** + +The OffsetPaginator will apply pagination by sending two **query parameters**: + +* limit +* offset + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects the "top" and a "skip" query parameters instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): OffsetPaginator
+{
+    return new class(connector: $this, request: $request) extends OffsetPaginator
+    {
+        protected ?int $perPageLimit = 100;
+    
+        protected function isLastPage(Response $response): bool
+        {
+            return $this->getOffset() >= (int)$response->json('total');
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            $request->query()->merge([
+                'top' => $this->perPageLimit,
+                'skip' => $this->getOffset(),
+            ]);
+    
+            return $request;
+        }
+    };
+}
+
+ +{% hint style="info" %} +The `getOffset()` method is a useful helper that calculates the current offset for you based on current interation and the per-page limit. +{% endhint %} + +### **Useful Methods/Properties On The OffsetPaginator** + +We previously mentioned that the `OffsetPaginator` class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **page** - An integer which will return the current page that the paginator is currently on. +* **getOffset()** - A helpful method that calculates the current offset for you based on current interation and the per-page limit. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. + +]]> +
+ +<?php + +use Saloon\Http\Response; +use Saloon\Http\Connector; +use Saloon\PaginationPlugin\PagedPaginator; +use Saloon\PaginationPlugin\Contracts\HasPagination; + +class SpotifyConnector extends Connector implements HasPagination +{ + // ... + + public function paginate(Request $request): PagedPaginator + { + return new class(connector: $this, request: $request) extends PagedPaginator + { + // + }; + } +} + + +{% hint style="info" %} +You don't need to use an anonymous class if it doesn't fit your code style. It is recommended to reduce the number of classes, but you can create your own pagination class that extends the base paginator if you prefer. +{% endhint %} + +After you have defined your paginator class, you will be required to define two protected methods which are used to power the paginator. These methods are: + +* **isLastPage** - This method is used to tell the paginator when to stop processing. Here you can use the response class provided to determine if you are on the last page. Some APIs may provide metadata like remaining results or next page URLs which you can use to check if you are on the last page. Additionally, Saloon has a few properties that can be used to determine if you are on the last page. +* **getPageItems** - This method is used to return the array of results inside of each page. This is used when using the `items` or `collect` method on your paginator class. + +Let's implement these two methods on our paginator and dive into how it works. + +```php +json('next_page_url')); + } + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +Let's assume in this hypothetical example that the API provides some useful information to see if we're on the last page. In this example, we know we're on the last page if the `next_page_url` JSON property on the body is null. There are various other ways of knowing if you are on the last page, so it's best to fully understand your API's pagination. + +To get the page items, we'll use the `json` method on the response to access the `items` array from the body. + +### Specifying a default per-page on the paginator + +The third-party API you are integrating with may require you to define a page size (per page) on your requests, or you may want to set a default page size used for every request. You can set this default page size as a property on the paginator class. + +
public function paginate(Request $request): PagedPaginator
+{
+    return new class(connector: $this, request: $request) extends PagedPaginator
+    {
+        protected ?int $perPageLimit = 100;
+        
+        // ...
+    }
+}
+
+ +You may also use the `setPerPageLimit` method on an instantiated paginator if you want to configure it on the fly. **You must set this before iterating over the paginator.** + +```php +$spotifyConnector = new SpotifyConnector; + +$paginator = $spotifyConnector->paginate($request); + +$paginator->setPerPageLimit(250); + +// foreach($paginator as $response) { ... } +``` + +### **Assumptions made with the PagedPaginator** + +The PagedPaginator will apply pagination by sending two **query parameters**: + +* page +* per\_page + +This assumption might not be the way your third-party API works. You can really easily change this by extending the `applyPagination` method. For example, let's say our API expects a "currentPage" and a "pageSize" instead. We can simply extend the `applyPagination` method and change the keys. You can apply the pagination in whichever the API requires. + +
public function paginate(Request $request): PagedPaginator
+{
+    return new class(connector: $this, request: $request) extends PagedPaginator
+    {
+        protected function isLastPage(Response $response): bool
+        {
+            return is_null($response->json('next_page_url'));
+        }
+        
+        protected function getPageItems(Response $response, Request $request): array
+        {
+            return $response->json('items');
+        }
+        
+        protected function applyPagination(Request $request): Request
+        {
+            $request->query()->add('currentPage', $this->currentPage);
+    
+            if (isset($this->perPageLimit)) {
+                $request->query()->add('pageSize', $this->perPageLimit);
+            }
+    
+            return $request;
+        }
+    };
+}
+
+ +### **Useful Properties On The PagedPaginator** + +We previously mentioned that the PagedPaginator class provides a few methods that can be used to help with last-page calculation. These methods are: + +* **totalResults** - An integer which will return the total number of items returned. This can be used to check if it's equal to the number of total results in the list. +* **currentPage** - An integer which will return the current page that the paginator is currently on. + +### Next Steps + +After configuring your paginator, head back to the [Using The Paginator](./#using-the-paginator) section of the documentation. + +]]> +
+ +paginate(new GetLikedSongsRequest); + +foreach($likedSongs->items() as $likedSong) { + // e.g. Luke Combs - When It Rains It Pours 🎵 +} +``` + +{% hint style="info" %} +Saloon's paginators are versatile and can work with any API format, including JSON, XML, and even multipart responses. +{% endhint %} + +### Getting Started + +Saloon's paginators are provided through a plugin. First, install the following package with Composer. + +```sh +composer require saloonphp/pagination-plugin "^2.0" +``` + +### Making your requests pageable + +Once the pagination plugin is installed, you must implement an interface on the requests that use pagination. This interface enables the paginator to decide whether or not to try pagination. It's important to do this as it avoids developer mistakes and potentially causing infinite loops. + +All you need to do is add the `Paginatable` interface to your requests. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\PaginationPlugin\Contracts\Paginatable;
+
+class GetLikedSongsRequest extends Request implements Paginatable
+{
+    // ...
+}
+
+ +After that, you need to add the `HasPagination` interface to your connector. This will require you to define a `paginate` method which we will implement next. + +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\PaginationPlugin\Paginator;
+use Saloon\PaginationPlugin\Contracts\HasPagination;
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    // ...
+    
+    public function paginate(Request $request): Paginator
+    {
+        //
+    }
+}
+
+ +Now you need to choose a paginator that corresponds to the pagination type used by the third-party API. This documentation is divided into three sections based on Saloon's three pre-installed paginators. + +{% content-ref url="paged-pagination.md" %} +[paged-pagination.md](paged-pagination.md) +{% endcontent-ref %} + +{% content-ref url="limit-offset-pagination.md" %} +[limit-offset-pagination.md](limit-offset-pagination.md) +{% endcontent-ref %} + +{% content-ref url="cursor-pagination.md" %} +[cursor-pagination.md](cursor-pagination.md) +{% endcontent-ref %} + +### Building Your Own Paginators + +Sometimes an API may implement their own kind of pagination and Saloon might not have a pagination supported out of the box for it. You can create your own paginators really easily. Follow the link below for building your own paginators. + +{% content-ref url="custom-pagination.md" %} +[custom-pagination.md](custom-pagination.md) +{% endcontent-ref %} + +### Using The Paginator + +After you have configured your paginator, it's time to start using it! There are various ways to use the paginator, so we'll cover them in this part of the guide. First, let's take a look at how we instantiate our paginator. When we instantiate the paginator - Saloon won't make any requests. The requests are only made when we start iterating over the paginator. + +```php +paginate(new GetLikedSongsRequest); +``` + +As you can see, instantiating the paginator is as simple as running the method and passing in the paginatable request. We are now ready to start using the paginator. + +#### Iterating Over Responses + +The simplest way to start using the paginator is to use it inside of a `foreach` loop. This will return each page as a Saloon `Response` for you to access. Saloon will only keep one response in memory at a time so you won't have to worry about running out of memory. + +```php +paginate(new GetLikedSongsRequest); + +foreach($paginator as $response) { + $status = $response->status(); + $data = $response->body(); +} +``` + +#### Iterating Over Items + +One of the more exciting methods Saloon provides is the `items` method. This cool method will give you each item across multiple pages. With this, you can handle the individual items. This uses the `getPageItems` method which you defined earlier in your paginator. + +```php +paginate(new GetLikedSongsRequest); + +foreach($paginator->items() as $song) { + $songName = $song['name']; + $songArtists = $song['artists']; +} +``` + +#### Using Laravel Collections (LazyCollection) + +Another really cool method Saloon provides is the `collect` method. If you are using Laravel with Saloon, this method will work out of the box, but if you aren't using Laravel - you can add the support for this method by installing the "collections" library via Composer. + +```bash +composer require illuminate/collections +``` + +This method will return a `LazyCollection` class. This class extends Laravel's base `Collection` class but works with custom iterators and keeps memory consumption low. The `LazyCollection` is really powerful when it comes to processing results from a paginated API. You can use the collection to filter, map, sort and much more all within just one iteration! + +```php +paginate(new GetLikedSongsRequest); +$collection = $paginator->collect(); + +$results = $collection + ->filter(function (array $song) { + return count($song['artists']) > 1; + }) + ->map(function (array $song) { + return $song['name']; + }) + ->sort(); + +foreach($results as $song) { + // $song: "When It Rains It Pours" +} +``` + +Even though in this example, we are doing multiple operations (filter, map, sort) the transformation will only happen when we iterate through the `LazyCollection` making it very performant and easy on system memory. + +By default, Saloon will iterate through each result within each API page, but if you would rather have a collection that iterates through `Response` classes, you may do this too. Just set the `throughItems` argument to false. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$collection = $paginator->collect(throughItems: false);
+
+ +{% hint style="info" %} +To see a full list of available methods on the `LazyCollection` you can [click here to read](https://laravel.com/docs/collections) the Laravel Documentation on Collections. +{% endhint %} + +### Advanced Features + +Saloon's paginators are a fantastic way of iterating through many page-separated results quickly and easily without writing boilerplate code in your application. So far we've covered the basics of pagination, but there's still plenty you can do. Within this section of the guide, we'll go through some more advanced features. + +#### Casting Items Into DTOs + +Saloon has a great way of casting responses into DTOs, but what if instead of getting the raw array or string item for each item in the paginator you wanted to resolve your DTO? You can simply use your `dto` or `dtoOrFail` method inside of the `getPageItems` method of your paginator. By using this method, you already have configured your DTO building logic on your connector. If you're not sure how to do this, [click here](../../the-basics/data-transfer-objects.md). + +{% tabs %} +{% tab title="Paginator Config" %} +
class SpotifyConnector extends Connector implements HasPagination
+{
+    public function paginate(Request $request): PagedPaginator
+    {
+        return new class(connector: $this, request: $request) extends PagedPaginator
+        {
+            // ...
+            
+            protected function getPageItems(Response $response, Request $request): array
+            {
+                return $response->dto();
+            }
+        }
+    }
+}
+
+{% endtab %} + +{% tab title="Request" %} +
<?php
+
+class GetLikedSongsRequest extends Request
+{
+    // {...}
+    
+    public function createDtoFromResponse(Response $response): array
+    {
+        return array_map(function (array $song) {
+            return Song::fromArray($song);
+        }, $response->json('items'));
+    }
+}
+
+{% endtab %} +{% endtabs %} + +{% hint style="info" %} +The `createDtoFromResponse` method on your request/connector must return an array. +{% endhint %} + +You can also implement the DTO conversion logic inside of the `getPageItems` method like below. + +```php +protected function getPageItems(Response $response, Request $request): array +{ + return array_map(function (array $song) { + return Song::fromArray($song); + }, $response->json('items')); +} +``` + +#### Asynchronous Pagination / Pooling + +You may prefer to send your requests asynchronously or use a request pool for better performance. To get started with this, you must implement a new method on your paginator called `getTotalPages`. This method is invoked after the first request and is used to determine how many additional requests Saloon needs to send. + +Let's start with defining our `getTotalPages` method. Some APIs may not return this information, and unfortunately, if they do not return this information then you may not be able to do asynchronous pagination. + +
<?php
+
+class SpotifyConnector extends Connector implements HasPagination
+{
+    public function paginate(Request $request): PagedPaginator
+    {
+        return new class(connector: $this, request: $request) extends PagedPaginator
+        {
+            // ...
+            
+            protected function getTotalPages(Response $response): int
+            {
+                return $response->json('total_results');
+            }
+        }
+    }
+}
+
+ +Next, instantiate your paginator and use the `async` method to enable asynchronous pagination. Now when you iterate through results, you will get a `Promise` instance instead of a Saloon Response. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$paginator->async();
+
+foreach($paginator as $promise) {
+    // $promise->then()
+}
+
+ +You can also use a paginator pool. If you are unfamiliar with how asynchronous request pools work, [check out this section of the documentation](../concurrency-and-pools.md) first. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$pool = $paginator->pool(concurrency: 10);
+
+$pool->withResponseHandler(function (Response $response) { 
+    // Handle each response
+
+    $status = $response->status();
+    $data = $response->body(); 
+});
+
+$promise = $pool->send();
+
+$promise->wait();
+
+ +#### Custom Per-Request Pagination + +Sometimes you may wish to use a different paginator on your request than your connector. For example, an API might not use the same pagination across all its endpoints. To get started with this - first, implement the `HasRequestPagination` interface on your request. This interface will expect you to define a `paginate` method on your request. + +```php +json('next_page_url')); + } + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +Next, you can pass the connector into your request to instantiate the paginator. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+$request = new GetLikedSongsRequest;
+
+$paginator = $request->paginate($spotifyConnector);
+
+ +#### Counting results + +You may wish to count the pages of the paginator. You can use the `count()` PHP method to get the total number of pages from a paginator. + +
<?php
+
+$spotifyConnector = new SpotifyConnector;
+
+$paginator = $spotifyConnector->paginate(new GetLikedSongsRequest);
+
+$pages = count($paginator);
+
+ +{% hint style="warning" %} +You should use the `count()` method and not `iterator_count()` on the paginator because `iterator_count()` is not supported and you may get inaccurate results. +{% endhint %} + +#### Handling Infinite Loops + +While building your paginators, sometimes, you might run into a situation when the paginator is attempting to get the same page over and over again, causing an infinite loop. This is usually caused by mis-configuring the `isLastPage` method. To try to mitigate infinite loops, the paginator has a built-in safety feature that will throw an exception if the last five responses have exactly the same body. + +Saloon will throw a `PaginationException` with a message like: + +> Potential infinite loop detected! The last 5 requests have had exactly the same body. + +If you would like to disable this check, you can set the `detectInfiniteLoop` property on your paginator to false. + +
public function paginate(Connector $connector): Paginator;
+{
+    return new class(connector: $connector, request: $this) extends PagedPaginator
+    {
+        protected bool $detectInfiniteLoop = false;
+    }
+}
+
+ +{% hint style="warning" %} +Detecting infinite loops with asynchronous pagination is not supported. +{% endhint %} + +]]> +
+
+ +send(new GetServersRequest); + +$psrResponse = $response->getPsrResponse(); +$psrRequest = $response->getPsrRequest(); +``` + +This design decision was made because the PSR-7 and 17 standards are very well-known and have been implemented by many popular HTTP clients. While Saloon uses Guzzle as the default way to send requests, if Guzzle suddenly becomes abandoned - Saloon can use one of many other HTTP clients without needing an entire rebuild from scratch. While Guzzle is amazing, and we'd never want it to go away - making Saloon independent of the HTTP client was a big step toward future-proofing the library. + +Another significant benefit to having PSR support is a better experience for you, the developer. With previous versions, Saloon heavily relied on Guzzle's config options to build the PSR-7 request internally, which meant that debugging was difficult because you never really knew what was sent to the third party. With version three, you can see the PSR request right before it is sent. If you want to learn more about debugging the PSR request, [click here](../the-basics/debugging.md). + +### Modifying the PSR-7 Request + +There may be a situation where you need to modify the PSR-7 request before it's sent to the HTTP client. You can use a special hook on either the connector or the request. This hook provides you with the built PSR-7 request that you can modify and return. To use this hook, extend the `handlePsrRequest` method on either your connector or request. + +If you use the method on the connector - the method will be run for every request sent through the connector. The method will give you access to both the PSR request and the Saloon `PendingRequest` if you need to use it for additional information, like the Saloon request class. + +```php +withHeader('X-API-Key', 'Howdy!'); + + return $request; + } +} +``` + +{% hint style="warning" %} +You may find it easier to modify the `Connector`, `Request`, or `PendingRequest` classes instead of the underlying PSR-7 request. You should be cautious when using this hook as there are many nicer, higher-level APIs in Saloon to modify the request. +{% endhint %} + +]]> + + +class ForgeConnector extends Connector +{ + public ?int $tries = 3; +} + + +Now when we send any request through this connector, if it fails it will be retried. + +```php +$forgeConnector = new ForgeConnector; + +$response = $forgeConnector->send(new UnreliableRequest); +``` + +If we get to attempt three and it still fails, Saloon will throw a `FatalRequestException` (for connection errors) or a `RequestException` for typical HTTP errors. + +{% hint style="warning" %} +The retry functionality will only work when sending requests synchronously. The retry logic will not work when using `sendAsync` or pools because Saloon needs to wait for a response to come back to determine if it needs to be retried. +{% endhint %} + +#### What does Saloon consider a failed request? + +By default, if the API couldn't be connected to or if the response status code is either a 4xx or 5xx, then Saloon will consider it a failed request. You can change this by extending the `hasRequestFailed` method on your connector. [Click here to learn more.](../the-basics/handling-failures.md#customising-when-saloon-thinks-a-request-has-failed) + +### Intervals + +You can also configure an interval in **milliseconds** that Saloon should wait between retries. You can configure an interval with the `$retryInterval` property. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?int $retryInterval = 1000;
+}
+
+ +#### Exponential Backoff + +You can also use exponential backoff when retrying which will double the retry interval after each unsuccessful attempt. This is useful as it can be less strenuous on the API if it is experiencing issues. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?int $retryInterval = 500;
+    
+    public ?bool $useExponentialBackoff = true;
+}
+
+ +### Exceptions + +By default, when all attempts have been exceeded, Saloon will either throw a `FatalRequestException` or a `RequestException`. You can choose to disable this behaviour and return the last response that Saloon received instead. + +If the exception was `FatalRequestException` then the exception will still be thrown as we wouldn't have a response to return. + +
class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public ?bool $throwOnMaxTries = false;
+}
+
+ +### Customising the request before the next retry + +In some situations, you might want to change the next request to improve the chances of the next retry being successful. You can overwrite the `handleRetry` method on the connector or request and use it to customise the `Request` class. You must also return a boolean in this method to tell Saloon if the retry should commence. + +
<?php
+
+use Saloon\Exceptions\RequestException;
+use Saloon\Http\Auth\TokenAuthenticator;
+use Saloon\Exceptions\FatalRequestException;
+use Saloon\Http\Request;
+    
+class ForgeConnector extends Connector
+{
+    public ?int $tries = 3;
+    
+    public function handleRetry(FatalRequestException|RequestException $exception, Request $request): bool
+    {
+        if ($exception instanceof RequestException && $exception->getResponse()->status() === 401) {
+            $request->authenticate(new TokenAuthenticator($this->getNewToken()));
+        }
+        
+        return true;
+    }
+}
+
+ +### Using the sendAndRetry method + +{% hint style="warning" %} +This method has been deprecated since Saloon v3.6.4 +{% endhint %} + +Saloon also has a `sendAndRetry` method which can be used on the fly on any connector or request without needing to configure anything. This method has the same functionality in the format of a method. + +```php +sendAndRetry( + request: new UnreliableRequest, + tries: 3, + interval: 500, + handleRetry: function (FatalRequestException|RequestException $exception, Request $request) { + // + }, + throw: true, + useExponentialBackoff: true, +); +``` + +]]> +
+ +send(); +``` + +]]> + +
+ + +send(new GetServersRequest); +$response->isCached(); // false + +// Next time it is sent... + +$response = $forge->send(new GetServersRequest); +$response->isCached(); // true +``` + +#### When will Saloon cache a request? + +Saloon will only cache a **successful** request when the method is either GET or OPTIONS. You can customise this by extending the `getCacheableMethods` method where you added the `HasCaching` trait. + +```php +invalidateCache(); + +$response = $forge->send($request); +``` + +### Temporarily Disabling Caching + +Sometimes you may wish to disable the caching on a per-request basis for debugging or to bypass caching. You can do this by using the `disableCaching` method on the request. + +```php +disableCaching(); + +$response = $forge->send($request); +``` + +### Source Code + +To view the source code of this plugin, [click here](https://github.com/Sammyjo20/saloon-cache-plugin). + +]]> + + +everyMinute(), + Limit::allow(1000)->everyDay(), + Limit::allow(5000)->everyMonth(), + ]; + } + + protected function resolveRateLimitStore(): RateLimitStore + { + $redis = new Redis; + $redis->connect('127.0.0.1'); + + return new RedisStore($redis); + } +} + +``` + +### Installation + +You can install this plugin via Composer. + +``` +composer require saloonphp/rate-limit-plugin "^2.0" +``` + +### Getting Started + +To use the plugin, add the `HasRateLimit` trait to your connector or request. If you have a connector, you should put it on the connector, but it can be put on an individual request if a specific endpoint has a different rate limit or if you are using solo requests. If you are using the trait on both your connector and request, the rate limits are combined together. + +```php +use Saloon\Http\Connector; +use Saloon\RateLimitPlugin\Traits\HasRateLimits; + +class SpotifyConnector extends Connector +{ + use HasRateLimits; +} +``` + +Next, you will be required to implement two methods: `resolveLimits` and `resolveRateLimitStore`. These methods allow you to define the limits that Saloon will keep track of and the store where the limit "hits" will be kept. + +```php +use Saloon\Http\Connector; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\MemoryStore; +use Saloon\RateLimitPlugin\Traits\HasRateLimits; + +class SpotifyConnector extends Connector +{ + use HasRateLimits; + + protected function resolveLimits(): array + { + return []; + } + + protected function resolveRateLimitStore(): RateLimitStore + { + return new MemoryStore; + } +} +``` + +### Stores + +Here are the various stores that the rate-limiting plugin supports. You may also [create your own stores](https://github.com/Sammyjo20/saloon-docs/blob/v2/digging-deeper/broken-reference/README.md) if this library does not come with the one you need. Stores are used to keep track of how many requests have been sent through a given connector/request. + +#### Available Stores + +* In-Memory (Array) +* File +* Redis +* Predis +* PSR Cache Store +* Laravel Cache Store + +#### Memory Store + +The simplest store. This store is persisted on the current instance of the connector/request and all information is lost when the connector is destructed. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\MemoryStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new MemoryStore; +} +``` + +#### File Store + +This store will use the local filesystem to store the limits. The only requirement for this store is for you to define the absolute path to a directory where you would like the limits to be stored. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\FileStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new FileStore('some/application/directory'); +} +``` + +#### Redis Store + +This store will use PHP's `Redis` extension to store the limits on a Redis database. You should pass the Redis configuration into this store. + +```php +use Redis; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\RedisStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + $client = new Redis; + $client->connect('127.0.0.1'); + + return new RedisStore($client); +} +``` + +#### Predis Store + +Similar to the `RedisStore`, the `PredisStore` allows you to connect to Redis through the `predis/predis` PHP library. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\PredisStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + $client = new Predis\Client([ + 'scheme' => 'tcp', + 'host' => '10.0.0.1', + 'port' => 6379, + ]); + + return new PredisStore($client); +} +``` + +#### PSR Cache Store + +This store supports any PSR-16 cache store provided by the `psr/simple-cache` library. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\PsrStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new PsrStore(new SomePsr16Store); +} +``` + +#### Laravel Cache Store + +This store can only be used in a Laravel environment but allows you to use any of Laravel's cache disks. + +```php +use Illuminate\Support\Facades\Cache; +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; +use Saloon\RateLimitPlugin\Stores\LaravelCacheStore; + +protected function resolveRateLimitStore(): RateLimitStore +{ + return new LaravelCacheStore(Cache::store('redis')); +} +``` + +### Limits + +While this plugin can detect if a 429 status occurs from a response, it's better to prevent your application from hitting rate limits than let them happen. This plugin provides an expressive `Limit` class which can be used to define different limits. You can define as many limits as you like, with various intervals. + +#### What limit type should I be using? + +The rate limit plugin supports two types of limits, time-based limiters, for example 100 requests every 60 seconds and a "Leaky Bucket" limiter. Please continue reading if you need to use time-based limiters or you can [click here for leaky bucket limiters](handling-rate-limits.md#leaky-bucket-limiter). + +#### Configuring Limits + +Here is a simple example of a limit for an API which only allows 60 requests per minute, but has a daily limit of 1,000 API calls. There are many different limit intervals, as well as different ways you can instruct Saloon to handle the limit. There is no restriction on the number of limits you can have. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->everyMinute(), + Limit::allow(1000)->everyDay(), + ]; +} +``` + +#### Limit Intervals + +There are various limit intervals which you can use on your limiter, ranging for seconds to up to the end of the month. + +```php +use Saloon\RateLimitPlugin\Limit; + +Limit::allow(60)->everySeconds(seconds: 5); +Limit::allow(60)->everyMinute(); +Limit::allow(60)->untilEndOfMinute(); +Limit::allow(60)->everyFiveMinutes(); +Limit::allow(60)->everyThirtyMinutes(); +Limit::allow(60)->everyHour(); +Limit::allow(60)->untilEndOfHour(); +Limit::allow(60)->everySixHours(); +Limit::allow(60)->everyTwelveHours(); +Limit::allow(60)->everyDay(); +Limit::allow(60)->everyDayUntil('8pm'); +Limit::allow(60)->untilMidnightTonight(); +Limit::allow(60)->untilEndOfMonth(); +``` + +#### Custom Names + +Sometimes you may need to add a name to your limiter. A good example of this is if you have separate API keys per user and therefore require a different API rate limit per user. You can add the `name()` method to your limit to specify a custom name for your limiter. Each limiter's name must be unique. + +```php +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->everyMinute()->name('spotify-limit-user-' . $this->userId), + ]; +} +``` + +#### Custom Prefixes + +Saloon will append the class name of the connector or a request as the prefix to the limiter name. For example SpotifyConnector:30\_every\_60. You may customise the prefix by extending the `getLimiterPrefix` method on your connector or request. + +```php +protected function getLimiterPrefix(): ?string +{ + return 'spotify-user-' . $this->userId; +} +``` + +#### Custom Thresholds + +You may want to specify the percentage threshold that Saloon should accept as the number of "hits" on a given limit. This is useful if you want to stay just under the real API limit while still defining the limit in the connector/request. + +The threshold must be a number between 0 and 1 (e.g 0.8 = 80%) + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60, threshold: 0.8)->everyMinute(), // Will fail when at 80% capacity + ]; +} +``` + +#### Sleep + +If would rather Saloon didn't throw an exception, you can use the `sleep` method when defining a limit. When using the sleep method, an exception won't be thrown. Instead, Saloon will wait the remaining number of seconds before a request is attempted again. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->sleep(), + ]; +} +``` + +#### "429: Too Many Attempts" Detection + +While it's recommended that you should define your limits above, Saloon will try to catch 429 "Too Many Attempts" errors from an API and will automatically mark a limit as "exceeded" if it sees this status. By default, Saloon will attempt to parse the `Retry-After` header to work out when a limit has been exceeded. If Saloon cannot calculate this, the limit will be released after 60 seconds. + +You can customise this behaviour by overwriting the `handleTooManyAttempts` method. + +```php +protected function handleTooManyAttempts(Response $response, Limit $limit): void +{ + if ($response->status() !== 429) { + return; + } + + $limit->exceeded( + releaseInSeconds: RetryAfterHelper::parse($response->header('Retry-After')), + ); +} +``` + +Alternatively, you may choose to disable this functionality. You can do this by setting the `detectTooManyAttempts` property to `false` in your connector/request's constructor. + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Stores\MemoryStore;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    public function __construct()
+    {
+        $this->detectTooManyAttempts = false;
+    }
+}
+
+ +When Saloon detects a rate limit has been exceeded, Saloon will throw a `RateLimitReachedException` . If you would like your application to sleep instead of throwing an exception you can extend the `getTooManyAttemptsLimiter` method and apply the `sleep` modifier + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Stores\MemoryStore;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    protected function getTooManyAttemptsLimiter(): ?Limit
+    {
+        return Limit::custom($this->handleTooManyAttempts(...))->sleep();
+    }
+}
+
+ +{% hint style="warning" %} +When using the `sleep` modifier, Saloon will automatically attempt to make another request after detecting a rate limit being reached in the response. This does not affect the retry definition you may have defined on your connector or request. +{% endhint %} + +### Leaky Bucket Limiter + +Some applications may implement a "Leaky Bucket" algorithm for their rate limits, essentially this means that while you are making requests, within a given time frame (usually every second) you "gain" additional requests you can make. For example if an API integration allowed 60 requests per minute but had a leak rate of 1 per second, you could in theory be constantly communicating with the API as long as you stay within the 60 request limit. + +The plugin implementation is really straight forward. In order to implement the above example you would write something like this. + +```php +use Saloon\RateLimitPlugin\Bucket; + +protected function resolveLimits(): array +{ + return [ + Bucket::capacity(60) + ->leak(1) + ->everySeconds(1) + ->sleep() + ]; +} +``` + +{% hint style="info" %} +The `Bucket` class extends the `Limit` class so you may use all of the limit intervals as defined above. +{% endhint %} + +You'll notice that it does an initial burst of 60 requests, then the bucket fills back up and the next second does 1 request, then the next second does 1 request, which adheres to our "leak 1 every 1 second" specification. + +### Handling Rate Limits Being Exceeded + +When a rate limit has been reached, Saloon will throw a `RateLimitReachedException`. This exception contains a `getLimit` method which may be used to see the limit that has thrown the exception and see the number of seconds to wait before a request can be sent again. This can be done with a simple try-catch approach or if you are using the provided Laravel job middleware, then you can instruct your jobs to wait until the limit has been lifted. + +#### Try/Catch + +As mentioned above, Saloon will throw an exception if a rate limit is reached or if the API returns a 429: Too Many Requests response. You could use a try/catch block to catch the exception and do something with the limit. For example, you may return an error to your users to let them know how long they need to wait - or you might retry the request later. If you are using Saloon in a context of a queued process, then you may want to retry the queued job in the future, from the remaining seconds. + +```php +use Saloon\RateLimitPlugin\Exceptions\RateLimitReachedException; + +$spotify = new SpotifyConnector; + +try { + $response = $spotify->send(new GetPlaylistRequest); +} catch (RateLimitReachedException $exception) { + $seconds = $exception->getLimit()->getRemainingSeconds(); + + // Return our users back to our application with a custom response that could be + // shown on the front end. + + return response("Too many requests to Spotify's API. Please try again in ${$seconds} seconds."); +} +``` + +#### Sleep + +If would rather Saloon didn't throw an exception, you can use the `sleep` method when defining a limit. When using the sleep method, an exception won't be thrown. Instead, Saloon will wait the remaining number of seconds before a request is attempted again. + +```php +use Saloon\RateLimitPlugin\Limit; + +protected function resolveLimits(): array +{ + return [ + Limit::allow(60)->sleep(), + ]; +} +``` + +#### Laravel Job Middleware + +If you are using Laravel, then this library comes with a [job middleware](https://laravel.com/docs/queues#job-middleware) that you can use. This job middleware will catch the `RateLimitReachedException` and automatically release your job back onto the queue with the remaining seconds added. Add this to the `middleware` method on your Laravel Job. + +```php +use Saloon\RateLimitPlugin\Helpers\ApiRateLimited; + +public function middleware(): array +{ + return [new ApiRateLimited]; +} +``` + +{% hint style="info" %} +You may also wish to increase your job's tries when using this middleware in case the job needs to be retried multiple times. +{% endhint %} + +### Creating your own store + +You may create your own rate limit store by implementing the `RateLimitStore` interface. + +```php +use Saloon\RateLimitPlugin\Contracts\RateLimitStore; + +class CustomStore implements RateLimitStore +{ + /** + * Get a rate limit from the store + */ + public function get(string $key): ?string + { + // + } + + /** + * Set the rate limit in the store + */ + public function set(string $key, string $value, int $ttl): bool + { + // + } +} +``` + +### Disabling Rate Limiting + +Sometimes you might want to disable rate limiting by default or even disable it on a per-connector basis. You can either use a property to disable the rate-limiting functionality by default, or you can use the `useRateLimitPlugin()` method to disable it on a per-instance basis. + +
use Saloon\Http\Connector;
+use Saloon\RateLimitPlugin\Traits\HasRateLimits;
+
+class SpotifyConnector extends Connector
+{
+    use HasRateLimits;
+    
+    public function __construct()
+    {
+        $this->rateLimitingEnabled = false;
+    }
+}
+
+// Or...
+
+$connector = new SpotifyConnector;
+$connector->useRateLimitPlugin(false);
+
+ +]]> +
+ +CommandDescriptionphp artisan saloon:connectorCreates a new connector - You can provide an optional --oauth option if you would like to create an OAuth2 connector.php artisan saloon:requestCreates a new requestphp artisan saloon:responseCreates a custom responsephp artisan saloon:pluginCreates a pluginphp artisan saloon:authCreates a custom authenticatorphp artisan saloon:listList all your API integrations + +### Saloon Facade + +The Laravel plugin also provides a facade which can be used to feel more unified with the rest of Laravel. You can use the Facade in tests instead of the `MockClient::global()` method. + +```php +use Saloon\Laravel\Facades\Saloon; + +Saloon::fake([ + GetServersRequest::class => MockResponse::make(body: '', status: 200), +]); +``` + +To learn more about testing API integrations, [click here](../the-basics/testing/). + +### Laravel Nightwatch Support + +From v3.6.0 the Saloon Laravel plugin natively supports Laravel Nightwatch. The plugin will automatically register a Nightwatch middleware on all of your connectors. + +### Laravel Telescope Support + +From v3.8.0 the Saloon Laravel plugin natively supports Laravel Telescope. The plugin will automatically register a Telescope middleware on all of your connectors. + +### Events + +With the Laravel plugin installed, Saloon will start sending events when requests are being sent. These events are: + +* SendingSaloonRequest +* SentSaloonRequest + +These events can be added to your `EventServiceProvider` and you can create listeners to handle when these happen. + +### Laravel Zero + +If you are using [Laravel Zero](https://github.com/laravel-zero/laravel-zero), the `SaloonServiceProvider` that registers the `Saloon` facade as well as some default middleware might not be registered. You can register Saloon's service provider in your `AppServiceProvider.php`'s `register()` method definition. + +```php +app->register(SaloonServiceProvider::class); +} +``` + +]]> + + +expect('App\Http\Integrations\Integration\Connector') + ->toExtend('Saloon\Http\Connector') + ->toUse('Saloon\Traits\Plugins\AcceptsJson') + ->toUse('Saloon\Traits\Plugins\AlwaysThrowOnErrors'); +``` + +So that test is ensuring our class extends the base Connector and uses the `AcceptJson` and `AlwaysThrowOnErrors` traits. Whilst that test works, we could perhaps make it quicker to write and easier to read, so with Lawman, you can do: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toUseAcceptsJsonTrait() + ->toUseAlwaysThrowOnErrorsTrait(); +``` + +Next up, let's take a Request test that we have: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toExtend('\Saloon\Http\Request') + ->toImplement('Saloon\Contracts\Body\HasBody') + ->toUse('Saloon\Traits\Body\HasFormBody') + ->toUse('Saloon\Traits\Plugins\AcceptsJson'); +``` + +Lawman makes this test much nicer to read: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toBeSaloonRequest() + ->toSendPostRequest() + ->toHaveFormBody() + ->toUseAcceptsJsonTrait(); +``` + +What about if we want to test our Connector has an Authentication method? Lawman makes this easy to do, it even works with multi auth: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toUseCertificateAuthentication() + ->toUseTokenAuthentication(); +``` + +Lawman also has Expectations for the Pagination, Cache and Rate Limit Plugins: + +```php +test('request') + ->expect('App\Http\Integrations\Integration\Requests\Request') + ->toBeSaloonRequest() + ->toSendPostRequest() + ->toUsePagedPagination() + ->toHaveCaching() + ->toHaveRateLimits() +``` + +Maybe our Connector has some Retry instructions that we want to test. Again, with Lawman, it's as simple as: + +```php +test('connector') + ->expect('App\Http\Integrations\Integration\Connector') + ->toBeSaloonConnector() + ->toBeTriedAgainOnFailure() + ->toHaveRetryInterval() + ->toUseExponentialBackoff() +``` + +### Available Expectations + +#### Authentication + +* `toUseTokenAuthentication` +* `toUseBasicAuthentication` +* `toUseCertificateAuthentication` +* `toUseHeaderAuthentication` + +#### Cache + +* `toHaveCaching` + +#### Connector + +* `toBeSaloonConnector` + +#### Pagination + +* `toUsePagedPagination` +* `toUseOffsetPagination` +* `toUseCursorPagination` +* `toUseCustomPagination` + +#### Properties + +* `toSetConnectTimeout` +* `toSetRequestTimeout` +* `toBeTriedAgainOnFailure` +* `toHaveRetryInterval` +* `toUseExponentialBackoff` +* `toThrowOnMaxTries` + +#### Rate Limit + +* `toHaveRateLimits` + +#### Request + +* `toBeSaloonRequest` +* `toHaveRequestMethod` +* `toSendGetRequest` +* `toSendPostRequest` +* `toSendHeadRequest` +* `toSendPutRequest` +* `toSendPatchRequest` +* `toSendDeleteRequest` +* `toSendOptionsRequest` +* `toSendConnectRequest` +* `toSendTraceRequest` +* `toHaveJsonBody` +* `toHaveMultipartBody` +* `toHaveXmlBody` +* `toHaveFormBody` +* `toHaveStringBody` +* `toHaveStreamBody` + +#### Response + +* `toBeSaloonResponse` + +#### Trait + +* `toUseAcceptsJsonTrait` +* `toUseAlwaysThrowOnErrorsTrait` +* `toUseTimeoutTrait` +* `toUseAuthorisationCodeGrantTrait` +* `toUseClientCredentialsGrantTrait` + +### Contributing + +Contributions to Lawman are welcome! If you can think of an Expectation that would be useful for others to utilise in their tests, please submit a PR on GitHub. The only real rules are: + +* All Expectations must have a test to cover it +* A new Fixture class should be added for every new Expectation + +If you just follow how previous Expectations are done, then you should be good. + +### Reporting an Issue + +If you do spot an issue with Lawman, please [open an issue](https://github.com/JonPurvis/lawman/issues) on GitHub. + +]]> + + +
+ +### Installation + +You can install the Saloon SDK Generator through Composer. You can install it globally on your machine and have a simple CLI to generate SDKs. + +```sh +composer global require crescat-io/saloon-sdk-generator +``` + +{% hint style="info" %} +The library requires PHP 8.1 and above +{% endhint %} + +### Basic Usage + +To generate the PHP SDK from an API specification file, run the following command: + +```sh +sdkgenerator generate:sdk API_SPEC_FILE.{json|yaml|yml} + --type={postman|openapi} + [--name=SDK_NAME] + [--output=OUTPUT_PATH] + [--namespace=Company\\Integration] + [--force] + [--dry] + [--zip] +``` + +Replace the placeholders with the appropriate values: + +* `API_SPEC_FILE`: Path to the API specification file (JSON or YAML format). +* `--type`: Specify the type of API specification (`postman` or `openapi`). +* `--name`: (Optional) Specify the name of the generated SDK (default: Unnamed). +* `--namespace`: (Optional) Specify the root namespace for the SDK (default: `App\\Sdk`). +* `--output`: (Optional) Specify the output path where the generated code will be created (default: ./Generated). +* `--force`: (Optional) Force overwriting existing files. +* `--dry`: (Optional) Perform a dry run. It will not save generated files, only show a list of them. +* `--zip`: (Optional) Use this flag to generate a zip archive containing all the generated files. + +### Full Documentation + +The full documentation can be found by visiting the Github repository here: + +{% embed url="https://github.com/crescat-io/saloon-sdk-generator" %} + +### Issue Tracking + +As this is not directly affiliated with Saloon, please report any issues you have directly on the repository linked above. + +]]> +
+ +<?php + +trait HasLogging +{ + public function bootHasLogging(PendingRequest $pendingRequest): void + { + ray($pendingRequest); + } +} + + +{% hint style="warning" %} +You must not use `$this` inside of the trait, as mutating the original request or connector is discouraged. The PendingRequest is the source of truth while a request is being sent. +{% endhint %} +{% endtab %} + +{% tab title="Usage (Connector)" %} +
<?php
+
+class ForgeConnector extends Connector
+{
+    use HasLogging;
+}
+
+{% endtab %} +{% endtabs %} + +When you send your request, plugins are the first things that are invoked, even before the `boot` method. This is to allow maximum compatibility with [middleware ](../digging-deeper/middleware.md)and [authenticators](../the-basics/authentication.md). This also means that because it's the first process in the chain, other steps like middleware and the boot method will be able to overwrite anything added by a plugin. + +
+ +Because we added the trait to our connector, every request will use the `HasLogging` plugin. If you would like the plugin to be applied to just one request, you can add the plugin to the request only. + +{% hint style="warning" %} +Take caution when adding the plugin to both the connector and the request, because the plugin will be executed twice. +{% endhint %} + +]]> +
+ +values(); // ['breakfast_menu' => [['name' => '...'], ['name' => '...'], ['name' => '...']] + +// Query the XML + +$reader->value('food.0')->sole(); // ['name' => 'Belgian Waffles', 'price' => '$5.95', ...] + +$reader->xpathValue('//food[@bestSeller="true"]/name')->get(); // ['Belgian Waffles', 'Berry-Berry Belgian Waffles'] + +$reader->element('food.0')->sole()->getAttributes(); // ['soldOut' => false, 'bestSeller' => true] +``` +{% endtab %} + +{% tab title="XML" %} +```xml + + + Belgian Waffles + $5.95 + Two of our famous Belgian Waffles with plenty of real maple syrup + 650 + + + Strawberry Belgian Waffles + $7.95 + Light Belgian waffles covered with strawberries and whipped cream + 900 + + + Berry-Berry Belgian Waffles + $8.95 + Light Belgian waffles covered with an assortment of fresh berries and whipped cream + 900 + + +``` +{% endtab %} +{% endtabs %} + +### Documentation + +Click the card below to read the documentation + +{% embed url="https://github.com/saloonphp/xml-wrangler" %} + +### Saloon Integration + +XML Wrangler is also integrated with Saloon! Once installed, you'll be able to use the `xmlReader()` method on your responses to instantiate an XML Wrangler reader. + +```php +$response = $connector->send($request); + +$reader = $response->xmlReader(); + +// $reader->values(); +// etc... +``` + +#### Request Body + +You may also choose to use XML Wrangler to create the request body when sending XML requests in Saloon. + +```php +write('root', [ + 'ubuntu-version' => $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]); + + // Same as... + + // + // + // ubuntuVersion + // type + // provider + // + } +} +``` + +]]> + +
+ +

Introducing Saloon v3

+ +### Key Features + +* Lightweight, only depends on one library - Guzzle. +* Offers "Connector" and "Request" classes to encapsulate API integrations into files +* Allows you to record real requests in your tests so you have accurate testing data for your assertions. +* Works in any PHP framework, or just regular PHP applications (with Composer) +* Comes with powerful plugins to handle caching, rate limits, data transfer objects, XML, and more + +{% content-ref url="the-basics/installation.md" %} +[installation.md](the-basics/installation.md) +{% endcontent-ref %} + +]]> +
+ + + + + +token); + } +} +``` + +### Basic Auth (Base64 Encoded) + +The `BasicAuthenticator` class can be used to add a `Authorization: Basic` header to the request. Just extend the `defaultAuth` method and return the authenticator class. + +```php +username, $this->password); + } +} +``` + +### Query Parameter + +The `QueryAuthenticator` class can be used to add a query parameter to requests. Just extend the `defaultAuth` method and return the authenticator class. + +```php +token); + } +} +``` + +### Certificate Auth + +The `CertificateAuthenticator` class can be used to authenticate with a custom client-side certificate. An optional password can be provided. Just extend the `defaultAuth` method and return the authenticator class. + +```php +path, $this->password); + } +} +``` + +### Header Auth + +The `HeaderAuthenticator` class can be used to authenticate with a custom header. Just extend the `defaultAuth` method and return the authenticator class. + +```php +token, 'X-API-KEY'); + } +} +``` + +### Multiple Authenticators + +You may need to use multiple authenticator classes together, like a certificate and an authorization token. You can use the `MultiAuthenticator` class for this scenario. + +```php +certificate), + new TokenAuthenticator($this->token), + ); + } +} +``` + +### Custom Authentication + +If your API integration requires a more complicated authentication process, you can create your own authenticator classes which can be used on your connector. This helps abstract any complicated logic away from the connector keeping it tidy. + +```php +headers()->add(...); + // $pendingRequest->config()->add(...); + } +} +``` + +```php +token); + } +} +``` + +### The authenticate method + +You may also use the `authenticate` method on your connector or request if you would like to use or overwrite an authenticator at runtime. + +```php +$forge = new ForgeConnector; + +$forge->authenticate(new TokenAuthenticator($user->forge_token)); + +// $forge->send(...) +``` + +{% hint style="info" %} +Only one authenticator can be used at the same time. +{% endhint %} + +]]> + + + 'application/json', + 'Content-Type' => 'application/json', + ]; + } + + protected function defaultAuth(): TokenAuthenticator + { + return new TokenAuthenticator($this->token); + } +} +``` + +Now that we have created the SDK class, all we need to do is instantiate it and provide the API token. We are now ready to send requests through our SDK. You may add your methods to this class as it is the root class of your SDK. + +```php +send($request); +``` + +With this method, it’s really simple to build your SDK. All you would need to do is create all the requests and then document them in your README. Developers using your SDK can just instantiate your SDK and then use the `send` methods. This also gives the developer freedom to customise the request's headers, config and query parameters if they choose to. + +### Sending Requests With Methods + +Sometimes you may want to make it easy for the developer to find all the methods that they need to call the API through your SDK. You can create methods on your connector which send an API request or you could write a "resource" class that contains lots of requests + +{% tabs %} +{% tab title="Definition" %} +```php +class Pokeapi extends Connector +{ + // ... + + public function allPokemon(int $page): Response + { + return $this->send(new GetAllPokemon($page)); + } +} +``` +{% endtab %} + +{% tab title="Usage" %} +```php +allPokemon(page: 1); +``` +{% endtab %} +{% endtabs %} + +### Request Resources/Groups + +The resource pattern can help you combine your SDK requests into simple groups that are easy for the developer to find and consume. First, we'll create a class that extends Saloon's `BaseResource` class. + +For this API, I will create a Pokémon resource which will group all the Pokémon requests together. Imagine a resource like a controller in an MVC framework like Laravel. You should pass any arguments the request needs through the method arguments. + +
<?php
+
+use Saloon\Http\BaseResource;
+use Saloon\Http\Response;
+
+class PokemonResource extends BaseResource
+{
+     public function all(int $page): Response
+     {
+         return $this->connector->send(new GetAllPokemon($page));
+     }
+     
+     public function get(int $id): Response
+     {
+         return $this->connector->send(new GetSinglePokemon($id));
+     }
+}
+
+ +#### Defining a resource on your connector + +Now we'll define a method on the connector which returns this resource class. Don't forget to pass the connector's instance (`$this`) into the resource. + +```php +class Pokeapi extends Connector +{ + // ... + + public function pokemon(): PokemonResource + { + return new PokemonResource($this); + } +} +``` + +Now all our users have to do is access the `pokemon()` method on the SDK class to get access to all the various requests that our SDK has to offer. + +```php +pokemon()->all(page: 1); + +$giratina = $pokeapi->pokemon()->get(id: 'giratina'); +``` + +### Custom Responses + +You may wish to customise the `Response` class that is returned by Saloon from your SDK connector. [Click here to read more about custom responses.](responses.md#custom-responses) + +### Additional Features + +Please read through the other sections of Saloon's documentation to see the other features that you can offer for your SDK. Every other feature like testing, authentication, failure handling is all supported for SDKs. + +### Testing + +When building an SDK, it's important to write tests that ensure the SDK calls the correct requests from an API and returns the right response, especially if you're converting the response into a data-transfer-object. [Read through the testing section of the documentation](building-sdks.md#testing) to get familiar with mocking and recording requests. + +]]> +
+ + If you have installed the Laravel plugin, you can use the **php artisan saloon:connector** command to create a connector. + +### Headers + +Most API integrations will have common headers used by all of its requests. You can extend the `defaultHeaders` method to define the headers. + +
class ForgeConnector extends Connector
+{
+    // ...
+
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'application/json',
+            'Accept' => 'application/json',
+        ];
+    }
+}
+
+ +You can also use the `headers` method on a connector instance. + +```php +$forge = new ForgeConnector; + +$forge->headers()->add('Content-Type', 'text/plain'); +``` + +### Timeout + +By default, Saloon will have a connection timeout of 10 seconds and a request timeout of 30 seconds. You can customise this by using the `HasTimeout` trait and specifying a `connectTimeout` and `requestTimeout` property. + +```php +use Saloon\Traits\Plugins\HasTimeout; + +class ForgeConnector extends Connector +{ + use HasTimeout; + + protected int $connectTimeout = 60; + + protected int $requestTimeout = 120; +} +``` + +### Constructor Arguments + +Since connectors are just classes, you can define a constructor to populate its default properties. For example, if the URL changes per user of your application you can define this as a constructor argument. + +```php +class ForgeConnector extends Connector +{ + public function __construct(protected readonly string $baseUrl) { + // + } + + public function resolveBaseUrl(): string + { + return $this->baseUrl; + } +} +``` + +```php +$connector = new ForgeConnector('https://forge.laravel.com/api/v1'); +``` + +### HTTP Client Config + +The connector uses a HTTP client to send the request. By default, this client is [Guzzle](https://github.com/guzzle/guzzle). If you would like to define Guzzle config options then you can extend the `defaultConfig` method. + +[Click here to see a list of the available options Guzzle provide.](https://docs.guzzlephp.org/en/stable/request-options.html) + +```php +class ForgeConnector extends Connector +{ + // ... + + public function defaultConfig(): array + { + return [ + 'stream' => true, + ]; + } +} +``` + +You can also use the `config` method on a connector instance. + +```php +$forge = new ForgeConnector; + +$forge->config()->add('stream', true); +``` + +]]> +
+ +json(); + + return new Server( + id: $data['id'], + name: $data['name'], + ipAddress: $data['ip'], + ); + } +} +``` + +This is what the `Server` DTO looks like: + +```php +send(new GetServerRequest(id: 12345)); + +// Create a DTO even if the response was a failure +$server = $response->dto(); + +// Create a DTO or throw an exception if the response is not successful +$server = $response->dtoOrFail(); +``` + +{% hint style="info" %} +Saloon will attempt to create a DTO from your response no matter the status of the response. This allows you to create "error" data transfer objects. If you don't want to use this functionality, you can use the `dtoOrFail` method which will throw a LogicException if the response is a failure. **You can customise what is considered a failed response** [**here**](handling-failures.md#customising-when-saloon-thinks-a-request-has-failed)**.** +{% endhint %} + +### PHPStan / TypeHinting DTOs + +Due to the way DTOs are created in Saloon, you can lose the type of DTO. This can reduce the developer experience. There are two ways to get around this issue. + +You can use an inline-doc block above the `dto`/`dtoOrFail` method call. + +```php +/** @var Server $server */ +$server = $response->dto(); +``` + +Or you can use the `createDtoFromResponse` method directly on your connector or request - which will use the return type specified. + +```php +$server = $request->createDtoFromResponse($response); +``` + +### Using a DTO to populate request data + +You may also allow your data transfer objects to go both ways, back into requests. You can do this easily with Saloon, just accept your DTO as an argument in the constructor of your request and then use the DTO to set default properties inside of the request. + +{% tabs %} +{% tab title="Definition" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Enums\Method;
+use Saloon\Http\Response;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class UpdateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::PUT;
+    
+    public function __construct(readonly protected Server $server)
+    {
+        //
+    }
+    
+    public function resolveEndpoint(): string
+    {
+        return '/servers/' . $this->server->id;
+    }
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'name' => $this->server->name,
+        ];
+    }
+    
+    public function createDtoFromResponse(Response $response): mixed
+    {
+        $data = $response->json();
+    
+        return new Server(
+            id: $data['id'],
+            name: $data['name'],
+            ipAddress: $data['ip'],
+        );
+    }
+}
+
+{% endtab %} + +{% tab title="Usage" %} +```php +send(new GetServerRequest(id: 12345)); +$server = $response->dto(); + +// Modify the server +$server->name = 'YEE-HAW-2'; + +// Update the server request + +$response = $connector->send(new UpdateServerRequest($server)); +``` +{% endtab %} +{% endtabs %} + +### Accessing the response from your DTO + +Sometimes debugging a DTO can be difficult, especially if you have passed the data object through your application and no longer have access to the original `Response` that you created the DTO from. Saloon can inject the response into your data transfer object for you if you use the `HasResponse` trait and the `WithResponse` interface. Let's add it to our existing `Server` DTO. + +
<?php
+
+use Saloon\Http\Response;
+use Saloon\Traits\Responses\HasResponse;
+use Saloon\Contracts\DataObjects\WithResponse;
+
+class Server implements WithResponse
+{
+    use HasResponse;
+
+    public function __construct(
+        public readonly int $id,
+        public readonly string $name,
+        public readonly string $ipAddress,
+    ){}
+}
+
+ +Now whenever we retrieve an instance of our data transfer object, you will be able to access the underlying response that was created with it! + +```php +dto(); + +$response = $server->getResponse(); +``` + +]]> +
+ +debug()->send($request); +``` +{% endtab %} + +{% tab title="Request" %} +```php +$connector = new ForgeConnector; + +$connector->send($request->debug()); +``` +{% endtab %} +{% endtabs %} + +You can provide the `die` argument if you would like to terminate the application after receiving the response. + +```php +$connector->debug(die: true)->send($request); +``` + +This will provide an output in your terminal/browser like this: + +``` +Saloon Request (UserRequest) -> array:6 [ + "connector" => "Saloon\Tests\Fixtures\Connectors\TestConnector" + "request" => "Saloon\Tests\Fixtures\Requests\UserRequest" + "method" => "GET" + "uri" => "https://tests.saloon.dev/api/user" + "headers" => array:2 [ + "Host" => "tests.saloon.dev" + "Accept" => "application/json" + ] + "body" => "" +] + +Saloon Response (UserRequest) -> array:3 [ + "status" => 200 + "headers" => [] + "body" => "{"name":"Sam"}" +] +``` + +{% hint style="warning" %} +This output will show the request just before it is sent to the sender. If the sender (like Guzzle) adds any additional headers or changes the request, these changes will not be displayed. +{% endhint %} + +### Separate Debuggers + +You may also use `debugRequest` and `debugResponse` independently if you would like to debug just the request or response respectively. + +```php +debugRequest(); // $connector->debugRequest(die: true); + +$connector->debugResponse(); // $connector->debugResponse(die: true); +``` + +### Custom Debugger Handlers + +You may also provide a closure to the `debugRequest` and `debugResponse` methods if you would like to write your own debugging implementations. + +```php +debugRequest(function (PendingRequest $pendingRequest, RequestInterface $psrRequest) { + ray($psrRequest); +}); + +$connector->debugResponse(function (Response $response, ResponseInterface $psrResponse) { + ray($psrResponse); +}); +``` + + +]]> + + +send(new ErrorRequest); + +$response->failed(); // true +$response->status(); // 500 +$response->body(); // {"message": "Server Error"} +``` + +### Always throw exceptions on failed requests + +You may wish to throw an exception whenever a request fails (4xx or 5xx response). You can add the `AlwaysThrowOnErrors` trait on your connector, and then every request that fails will throw an exception. + +```php +send(new ErrorRequest); + +// throws InternalServerErrorException (extends ServerException) + +$response->throw(); +``` + +### Response Exceptions + +Saloon's default exception handler contains the following exceptions based on the status code and severity of the exception. These are thrown depending on the method you use below. + +``` +SaloonException +├── FatalRequestException (Connection Errors) +└── RequestException (Request Errors) + ├── ServerException (5xx) + │ ├── InternalServerErrorException (500) + │ ├── ServiceUnavailableException (503) + │ └── GatewayTimeoutException (504) + └── ClientException (4xx) + ├── UnauthorizedException (401) + ├── PaymentRequiredException (402) + ├── ForbiddenException (403) + ├── NotFoundException (404) + ├── MethodNotAllowedException (405) + ├── RequestTimeOutException (408) + ├── UnprocessableEntityException (422) + └── TooManyRequestsException (429) +``` + +### Handling failures with promises + +When sending requests using `sendAsync` or using request pooling, you will receive a `PromiseInterface` instance. Since this class catches exceptions, Saloon will automatically pass the request exception in the `otherwise` block, and you do not have to use the `throw` method. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle successful response + }) + ->otherwise(function (RequestException $exception) { + // Handle failed request + }); +``` + +### Customising when Saloon thinks a request has failed + +You may integrate with an API which returns a 200 response status but with an error message in the response body. To handle this, you can extend the `hasRequestFailed` method on your connector or request. + +{% tabs %} +{% tab title="Connector" %} +
<?php
+
+use Saloon\Http\Connector;
+use Saloon\Http\Response;
+
+class ForgeConnector extends Connector
+{
+    // {...}
+    
+    public function hasRequestFailed(Response $response): ?bool
+    {
+        return str_contains($response->body(), 'Server Error');
+    }
+}
+
+{% endtab %} + +{% tab title="Request" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Http\Response;
+
+class ErrorRequest extends Request
+{
+    // {...}
+    
+    public function hasRequestFailed(Response $response): ?bool
+    {
+        return str_contains($response->body(), 'Server Error');
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Customising the request exception + +By default, Saloon will use the exceptions [listed above](handling-failures.md#response-exceptions), but you may choose to return your own exception if a request has failed. Just extend the `getRequestException` method on either your connector or request. You will receive an instance of the response and a sender exception, which may be nullable. + +{% tabs %} +{% tab title="Connector" %} +```php + +
+ + + + + +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasFormBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasFormBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasFormBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/x-www-form-urlencoded` header for you when using the `HasFormBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]; + } +} +``` + +Sometimes there can be too many items to define as constructor arguments. If this is the case for you, you can require the user to provide an array, or even a DTO to populate the default body of your request. + +{% tabs %} +{% tab title="Using an array" %} +```php +payload; + } +} +``` +{% endtab %} + +{% tab title="Using a DTO (Data Transfer Object)" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasFormBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasFormBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected Server $server
+    ){}
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'ubuntu_version' => $this->server->ubuntuVersion,
+            'type' => $this->server->type,
+            'provider' => $this->server->provider,
+        ];
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the form request body: + +* add(string $key, mixed $value) -> **Add items to the form body** +* remove(string $key) -> **Remove items from the form body** +* merge(…$values) -> **Merge another array of items into the form body** +* set(array $value) -> **Overwrite the form body entirely** +* all(): array -> **Get all the values of the form body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->add('ubuntu_version', '22.04'); + +$request->body()->merge([ + 'type' => 'app', + 'provider' => 'ocean2', +]); + +$body = $request->body()->all(); + +// array: [ +// 'ubuntu_version' => '22.04', +// 'type' => 'app', +// 'provider' => 'ocean2', +// ] +``` + +### Connector Body + +If you would like to also have form body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared form body across every request, like an authentication token. + +```php + 'Sam', + ]; + } +} +``` + +]]> +
+ +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; +use Saloon\Enums\Method; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasJsonBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/json` header for you when using the `HasJsonBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + $this->ubuntuVersion, + 'type' => $this->type, + 'provider' => $this->provider, + ]; + } +} +``` + +Sometimes there can be too many items to define as constructor arguments. If this is the case for you, you can require the user to provide an array, or even a DTO to populate the default body of your request. + +{% tabs %} +{% tab title="Using an array" %} +```php +payload; + } +} +``` +{% endtab %} + +{% tab title="Using a DTO (Data Transfer Object)" %} +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasJsonBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasJsonBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected Server $server
+    ){}
+    
+    protected function defaultBody(): array
+    {
+        return [
+            'ubuntu_version' => $this->server->ubuntuVersion,
+            'type' => $this->server->type,
+            'provider' => $this->server->provider,
+        ];
+    }
+}
+
+{% endtab %} +{% endtabs %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the JSON request body: + +* add(string $key, mixed $value) -> **Add items to the JSON body** +* remove(string $key) -> **Remove items from the JSON body** +* merge(…$values) -> **Merge another array of items into the JSON body** +* set(array $value) -> **Overwrite the JSON body entirely** +* all(): array -> **Get all the values of the JSON body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->add('ubuntu_version', '22.04'); + +$request->body()->merge([ + 'type' => 'app', + 'provider' => 'ocean2', +]); + +$body = $request->body()->all(); + +// array: [ +// 'ubuntu_version' => '22.04', +// 'type' => 'app', +// 'provider' => 'ocean2', +// ] +``` + +### Connector Body + +If you would like to also have JSON body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared JSON body across every request, like an authentication token. + +```php + 'Sam', + ]; + } +} +``` + +### JSON Flags + +When using the `HasJsonBody` trait, you may want to customise the flags used when encoding the body to be sent to the API you are integrating with. You may do this with the `setJsonFlags` method. It's recommended that you set this within the constructor of your request or connector to ensure that the flags are always used. + +For example, if I know that my JSON will contain URLs, but I don't want the URL slashes to be escaped, I can use the `JSON_UNESCAPED_SLASHES` flag. You can also specify multiple flags at once by using the `|` pipe to separate the flags. + +```php +body()->setJsonFlags(JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR); + } +} +``` + +]]> +
+ +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class UploadProfilePictureRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasMultipartBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasMultipartBody;
+
+class UploadProfilePictureRequest extends Request implements HasBody
+{
+    use HasMultipartBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: multipart/form-data` header for you when using the `HasMultipartBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### The MultipartValue + +To build up multipart data, Saloon uses a class `Saloon\Data\MultipartValue`. This class is used as a value object and when your request is sent, it will automatically be converted into a stream to be sent to the API. To see how to use this class, continue reading below. + +```php +filePath) + ]; + } +} +``` + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the multipart request body: + +* add(string $name, mixed $value, string $filename = null, array $headers = \[]) -> **Add a multipart value to the multipart body** +* attach(MultipartValue $value) -> **Attach a multipart directly to the multipart body** +* remove(string $key) -> **Remove an item from the multipart body** +* merge(... $arrays) -> **Merge another array of multipart values into the multipart body** +* set(array $value) -> **Overwrite the entire multipart body with a different set of values** +* all() -> **Get the array of multipart values** +* get(string $key) **-> Get an individual multipart value** +* isEmpty() **-> Check if the multipart body is empty** +* isNotEmpty() **-> Check if the multipart body is not empty** + +```php +body()->add( + name: 'picture', + contents: 'your-file-contents-or-stream', + filename: 'picture.png', // Optional file name + headers: [ + // Optional custom headers + ] +); + +// You may also get a multipart value by name. + +$request->body()->get('picture'); // MultipartValue class + +``` + +{% hint style="info" %} +The `contents` of the `MultipartValue` class can be either the raw-text contents of the file or a PHP stream/resource. +{% endhint %} + +### Connector Body + +If you would like to also have a multipart body on your connector, you can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the properties will be merged. This is useful if you want to have a shared value across every request. + +```php + +
+ +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add a trait to provide an implementation for the missing `body()` method. Saloon has a trait for all the common types of request bodies. + +Continue reading below to understand more about the specific body type that you need. + +{% content-ref url="json-body.md" %} +[json-body.md](json-body.md) +{% endcontent-ref %} + +{% content-ref url="multipart-form-body.md" %} +[multipart-form-body.md](multipart-form-body.md) +{% endcontent-ref %} + +{% content-ref url="stream-body.md" %} +[stream-body.md](stream-body.md) +{% endcontent-ref %} + +{% content-ref url="form-body-url-encoded.md" %} +[form-body-url-encoded.md](form-body-url-encoded.md) +{% endcontent-ref %} + +{% content-ref url="xml-body.md" %} +[xml-body.md](xml-body.md) +{% endcontent-ref %} + +{% content-ref url="string-plain-text-body.md" %} +[string-plain-text-body.md](string-plain-text-body.md) +{% endcontent-ref %} + +]]> + + +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStreamBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStreamBody;
+
+    protected Method $method = Method::POST;
+    
+    // Define our own Content-Type...
+    
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'text/plain',
+        ];
+    }
+}
+
+ +{% hint style="info" %} +Saloon won't add a Content-Type header for you for plain stream bodies so you must define the Content-Type or the API might not accept the data. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php +stream; + } +} +``` + +{% hint style="info" %} +Saloon can accept a PHP resource or a PSR `StreamInterface` Stream implementation as the stream. +{% endhint %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the stream request body: + +* set(resource|StreamInterface $value) -> **Set the stream** +* all(): StreamInterface -> **Get the stream** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set(fopen('cowboy-hat.png', 'r')); + +$body = $request->body()->all(); // Returns PSR StreamInterface +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php + +
+ +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasStringBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStringBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStringBody;
+
+    protected Method $method = Method::POST;
+    
+    // Define our own Content-Type...
+    
+    protected function defaultHeaders(): array
+    {
+        return [
+            'Content-Type' => 'text/plain',
+        ];
+    }
+}
+
+ +{% hint style="info" %} +Saloon won't add a Content-Type header for you for plain string bodies so you must provide your own Content-Type header. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasStringBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasStringBody;
+
+    protected Method $method = Method::POST;
+    
+    public function __construct(
+        protected string $ubuntuVersion,
+        protected string $provider
+    ){}
+    
+    protected function defaultBody(): string
+    {
+        return 'Howdy, Partner. I want a ' . $this->ubuntuVersion . ' server through ' . $this->provider . ' provider!';
+    }
+}
+
+ +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the string request body: + +* set(string $value) -> **Overwrite the string body entirely** +* all(): array -> **Get the string body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set('Howdy, Partner'); + +$body = $request->body()->all(); + +// string: 'plain-text-response-body' +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php + +
+ +<?php + +use Saloon\Http\Request; +use Saloon\Contracts\Body\HasBody; + +class CreateServerRequest extends Request implements HasBody +{ + protected Method $method = Method::POST; +} + + +Next, you will need to add the `HasXmlBody` trait to your request. This trait will implement the `body()` method that the `HasBody` interface requires. It also provides a method `defaultBody()` which you can extend to provide a default body on your request. + +
<?php
+
+use Saloon\Http\Request;
+use Saloon\Contracts\Body\HasBody;
+use Saloon\Traits\Body\HasXmlBody;
+
+class CreateServerRequest extends Request implements HasBody
+{
+    use HasXmlBody;
+
+    protected Method $method = Method::POST;
+}
+
+ +{% hint style="info" %} +Saloon will automatically send the `Content-Type: application/xml` header for you when using the `HasXmlBody` trait, however, if you would like to overwrite this behaviour then you can use the `defaultHeaders` method on the request or modify the headers before the request is sent. +{% endhint %} + +### Default Body + +There are a couple of ways to interact with the request body to prepare it to be sent. You can either use the methods mentioned below to add to the body on any given instance or you can use the `defaultBody` method on your request. This is recommended because you could then define any requirements as constructor arguments in your request and then standardise your request even more. + +```php + + + ' . $this->ubuntuVersion . ' + ' . $this->type . ' + ' . $this->provider . ' + + XML; + } +} +``` + +{% hint style="info" %} +While you are expected to return a raw string for the XML body, it can be tedious to write XML as text. We have built a library, [XML Wrangler](https://github.com/saloonphp/xml-wrangler) which allows you to read and write XML in a more developer-friendly way. +{% endhint %} + +### Interacting with the body() method + +While you can define the default body on your request, it might be useful to add or modify the body at runtime on a per-request basis. Saloon has the following methods to allow you to modify the XML request body: + +* set(string $value) -> **Overwrite the XML body entirely** +* all(): array -> **Get the XML body** +* isEmpty(): bool -> **Check if the body is empty** +* isNotEmpty(): bool -> **Check if the body is not empty** + +```php +body()->set(''); + +$body = $request->body()->all(); + +// string: 'plain-text-response-body' +``` + +### Connector Body + +You can add the same interface and trait to your connector. If you have the trait on both the connector and the request, the body on the request will take priority. If you have the body on just the connector but not on the request, the request will inherit the body on the connector. + +```php +'; + } +} +``` + +### XML Wrangler + +You may be interested in a third-party library written by the maintainer of Saloon - XML Wrangler. It provides a modern syntax for reading and writing XML in PHP. + +{% content-ref url="../../installable-plugins/xml-wrangler.md" %} +[xml-wrangler.md](../../installable-plugins/xml-wrangler.md) +{% endcontent-ref %} + +]]> +
+
+ + If you have installed the Laravel plugin, you can use the **php artisan saloon:request** command to create a request. + +### Headers + +Some API requests require headers to be sent. To define default headers on your request, you can extend the `defaultHeaders` method. These will be merged with the connector's headers. + +```php +class GetServersRequest extends Request +{ + // ... + + protected function defaultHeaders(): array + { + return [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]; + } +} +``` + +You can also use the `headers` method on a request instance. + +```php +$request = new GetServersRequest; + +$request->headers()->add('Content-Type', 'text/plain'); +``` + +### Query Parameters + +Some API requests require query parameters to be sent. You can extend the `defaultQuery` method to provide these query parameters. + +```php +class GetServersRequest extends Request +{ + // ... + + protected function defaultQuery(): array + { + return [ + 'sort' => 'name', // ?sort=name + 'filter[active]' => 'true', // ?filter[active]=true + ]; + } +} +``` + +You can also use the `query` method on a request instance. + +```php +$request = new GetServersRequest; + +$request->query()->add('sort', 'provider'); +``` + +{% hint style="info" %} +Different APIs sometimes require different query string formats. Saloon uses PHP's built-in [`http_build_query`](https://www.php.net/manual/en/function.http-build-query.php) function to create query strings, but if you need something different, you can reformat the query string in the `Connector::handlePsrRequest()` method (see [Modifying the PSR-7 Request](../digging-deeper/psr-support.md#modifying-the-psr-7-request). +{% endhint %} + +### Timeout + +By default, Saloon will have a connection timeout of 10 seconds and a request timeout of 30 seconds. You can customise this by using the `HasTimeout` trait and specifying a `connectTimeout` and `requestTimeout` property. + +```php +use Saloon\Traits\Plugins\HasTimeout; + +class GetServersRequest extends Request +{ + use HasTimeout; + + protected int $connectTimeout = 60; + + protected int $requestTimeout = 120; +} +``` + +### Constructor Arguments + +Since requests are just classes, you can define a constructor to populate the request's properties. For example, if you are getting a specific resource you would need to pass its ID into the request class. + +```php +class GetServerRequest extends Request +{ + protected Method $method = Method::GET; + + public function __construct(protected readonly string $id) { + // + } + + public function resolveEndpoint(): string + { + return '/servers/' . $this->id; + } +} +``` + +```php +$request = new GetServerRequest('5664b05b-8b32-4523-a0d5-837f5080417a'); +``` + +]]> + + +send($request); + +$status = $response->status(); +$body = $response->body(); +``` + +{% hint style="info" %} +By default, Saloon will not throw an exception if a synchronous request fails. [Refer to the handling failures section for handling errors.](handling-failures.md) +{% endhint %} + +### Useful Methods + +Below are some of the key methods provided by Saloon's `Response` class. + +
MethodDescription
statusReturns the response status code.
headersReturns all response headers
headerReturns a given header
bodyReturns the raw response body as a string
jsonRetrieves a JSON response body and json_decodes it into an array.
arrayAlias of json
collectRetrieves a JSON response body and json_decodes it into a Laravel Collection. Requires illuminate/collections.
objectRetrieves a JSON response body and json_decodes it into an object.
xmlReaderUsed for XML responses - returns a XML Wrangler reader. Requires saloonphp/xml-wrangler.
domUsed for HTML responses - returns a Symfony DOM Crawler instance. Requires symfony/dom-crawler.
streamReturns the response body as an instance of StreamInterface
saveBodyToFileAllows you to save the raw body to a file or open file resource.
dtoConverts the response into a data-transfer object. You must define your DTO first, click here to read more.
dtoOrFailWill work just like dto but will throw an exception if the response is considered "failed".
ok, successful, redirect, failed, clientError, serverErrorMethods used to determine if a request was successful or not based on status code. The failed method can be customised.
throwWill throw an exception if the response is considered "failed".
getPendingRequestReturns the PendingRequest class that was built up for the request.
getPsrRequestReturns the PSR-7 request that was built up by Saloon
getPsrResponseReturn the PSR-7 response that was built up by the HTTP client/sender.
+ +### Asynchronous Responses + +When `sendAsync` or concurrent requests, Saloon will respond with a `GuzzleHttp\Promise\PromiseInterface.` The promise will contain a `Response` a class described above. When the request fails, Saloon will not use the `then` method but return an instance of `RequestException`in the `otherwise` block. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle successful response + }) + ->otherwise(function (Exception $exception) { + // Handle failed request + }); + +$promise->wait(); // Force the promise to be resolved +``` + +### Custom Responses + +Sometimes you may want to use your response class. This is useful if you want to add your methods or overwrite Saloon's response methods. Saloon allows you to overwrite the response at a connector level for all requests or at a per-request level for a granular response. + +The simplest way of registering a custom response is to use the `$response` property on either the connector or request. + +{% tabs %} +{% tab title="Connector" %} +
class ForgeConnector extends Connector
+{
+    // ...
+    
+    protected ?string $response = CustomResponse::class;
+}
+
+{% endtab %} + +{% tab title="Request" %} +
class GetServersRequest extends Request
+{
+    // ...
+    
+    protected ?string $response = CustomResponse::class;
+}
+
+{% endtab %} +{% endtabs %} + +When you need a more advanced way to define a custom response, use the `resolveResponseClass` method on either the connector or request. + +{% tabs %} +{% tab title="Connector" %} +```php +class ForgeConnector extends Connector +{ + // ... + + public function resolveResponseClass(): string + { + return CustomResponse::class; + } +} +``` +{% endtab %} + +{% tab title="Request" %} +```php +class GetServersRequest extends Request +{ + // ... + + public function resolveResponseClass(): string + { + return CustomResponse::class; + } +} +``` +{% endtab %} +{% endtabs %} + +]]> +
+ +send($request); +``` + +### Asynchronous Requests + +To send an asynchronous request, use the `sendAsync` method, and you will receive an instance of `PromiseInterface`. You should define a `then` and `otherwise` method to receive the response or exception. + +```php +sendAsync(new GetServersRequest); + +$promise + ->then(function (Response $response) { + // Handle Response + }) + ->otherwise(function (RequestException $exception) { + // Handle Exception + }); + +$promise->wait(); // Force the promise to be resolved +``` + +{% hint style="info" %} +Saloon uses Guzzle's Promises library. [Click here to learn more](https://github.com/guzzle/promises) +{% endhint %} + +]]> + + + + MockResponse::make(body: '', status: 200), + ]); + + $connector = new ForgeConnector; + $connector->withMockClient($mockClient); +}); +``` + +You use the key of the MockClient to define a request that should be mocked. You can also use a URL pattern. You can use an asterisk (**\***) to act as a wild card. + +```php +$mockClient = new MockClient([ + 'forge.laravel.com/api/v1/servers' => MockResponse::make(body: '', status: 200), + 'forge.laravel.com/*' => MockResponse::make(body: '', status: 200), +]); +``` + +You can also use a sequence of responses which will be returned regardless of the API call. + +```php +$mockClient = new MockClient([ + MockResponse::make(body: 'First', status: 200), + MockResponse::make(body: 'Second', status: 200), + MockResponse::make(body: 'Third', status: 200), +]); +``` + +You can also use a closure for more advanced mock responses. + +```php +$mockClient = new MockClient([ + GetServersRequest::class => function (PendingRequest $pendingRequest) { + return MockResponse::make(...); + }, +]); +``` + +#### Manual Fake Responses + +There are two ways to define a response, you can do it manually with `MockResponse::make()` which is suitable for simple responses. It will accept three arguments: body, HTTP status code and headers. You may pass a string or an array into the body argument. If you provide an array, it will automatically be converted into JSON. + +```php +$mockClient = new MockClient([ + GetUserRequest::class => MockResponse::make( + body: ['user' => ['name' => 'Sam']], + status: 200, + headers: ['Content-Type' => 'application/json'] + ), +]); +``` + +#### Recorded Responses (Fixtures) + +The second way to define a response is with `MockResponse::fixture()` this is suitable for testing larger API responses or to save time. With this, Saloon will make a real API call for the first time, and then store the API call inside of a file in your application, so that when you run the test again, the response will be used and not make a real API call. + +```php +$mockClient = new MockClient([ + GetUserRequest::class => MockResponse::fixture('user'); +]); +``` + +### Testing your application + +Now that you have an idea of how testing works in Saloon, let's put it into practice. This section of the documentation will teach you how to write a MockClient for your application. This guide assumes you have already set up a test suite for your application. If you are new to testing, we recommend [PEST](https://pestphp.com/). + +{% hint style="info" %} +This section of the documentation uses the new **Global Mock Client** introduced in Saloon v3.5. Make sure that you are using this version of Saloon by running: `composer update "saloonphp/*"` +{% endhint %} + +#### Setup + +First of all, you will need to add a method which should run before every test in your application. Without this, the global mock client will leak into other tests and may break your test suite. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\Http\Faking\MockClient; + +uses() + ->beforeEach(fn () => MockClient::destroyGlobal()) + ->in(__DIR__); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\Http\Faking\MockClient; + +class RequestTest extends TestCase +{ + protected function setUp(): void + { + MockClient::destroyGlobal(); + } +} +``` +{% endtab %} +{% endtabs %} + +{% hint style="info" %} +If you are using Laravel and have installed the [Laravel plugin](../../installable-plugins/laravel-integration.md), you do not need to destroy the global mock client before each test as the plugin will do this for you. +{% endhint %} + +#### Writing tests + +Let's say that your application has a controller which queries the Laravel Forge API and stores the list of servers in the database. We'll use the global mock client to return fake data so we don't send an API call to the external API. + +Saloon will detect the global mock client and will use the mock response which you have defined instead of sending a real API call. It's recommended to define your mock at the top of a test. + +{% tabs %} +{% tab title="Test" %} +```php + MockResponse::make( + body: [ + 'data' => [ + ['name' => 'WEB-1', 'ip' => '192.168.0.1'], + ['name' => 'WEB-2', 'ip' => '192.168.0.2'], + ], + ], + status: 200, + ), + ]); + + $this->assertDatabaseCount('servers', 0); + + // Call our controller which will invoke the Saloon request + + $this + ->getJson('/api/servers/sync') + ->assertOk(); + + // Assert our database has created servers! + + $this->assertDatabaseCount('servers', 2); + + $this->assertDatabaseHas('servers', [ + 'name' => 'WEB-1', + 'ip' => '192.168.0.1', + ]); + + $this->assertDatabaseHas('servers', [ + 'name' => 'WEB-2', + 'ip' => '192.168.0.2', + ]); +}); +``` +{% endtab %} + +{% tab title="Controller Code" %} +```php +send(new GetServersRequest)->array('data'); + + foreach($servers as $server) { + DB::table('servers')->insert([ + 'name' => $server['name'], + 'ip' => $server['ip'], + ]); + } + + return response('Synced servers', 200); + } +} +``` +{% endtab %} +{% endtabs %} + +### Recording Requests (Fixtures) + +So far we have covered testing where you have to write your mock response yourself. This works well for small responses but most API responses will have a lot more data. As previously mentioned, Saloon supports recording requests in your tests. This works by allowing the test to make a real API call the first time and then on subsequent API calls, the same response will be used. + +This works by saving the response as a file in your application which can be committed in your project and used for later. + +{% hint style="warning" %} +Make sure that you do not accidentally store sensitive information from the real API call. You can read more about redacting fixtures [here](./#redacting-recorded-responses-fixtures). +{% endhint %} + +#### Example with fixtures + +Let's take a look at the example above but with fixtures, as you can see nothing else has to change except that we are using `MockResponse::fixture()`. It accepts one argument which is the name of the fixture. + +
<?php
+
+use Saloon\Http\Faking\MockClient;
+use Saloon\Http\Faking\MockResponse;
+
+test('can store servers in the database from laravel forge', function () {
+    MockClient::global([
+        GetServersRequest::class => MockResponse::fixture('servers'),
+    ]);
+
+    $this->assertDatabaseCount('servers', 0);
+    
+    // Call our controller which will invoke the Saloon request
+
+    $this
+        ->getJson('/api/servers/sync')
+        ->assertOk();
+        
+    // Assert our database has created servers!
+        
+    $this->assertDatabaseCount('servers', 2);
+    
+    $this->assertDatabaseHas('servers', [
+        'name' => 'REAL-SERVER-1',
+        'ip' => '192.168.0.1',
+    ]);
+    
+    $this->assertDatabaseHas('servers', [
+        'name' => 'REAL-SERVER-2',
+        'ip' => '192.168.0.2',
+    ]);
+});
+
+ +#### Customising Fixture Location + +By default, fixtures will be stored in `tests/Fixtures/Saloon`. You can customise the fixture location by using the `setFixturePath` method on the `MockConfig` class. + +```php +MockConfig::setFixturePath('tests/other-directory'); +``` + +#### Namespacing Fixtures + +With multiple API integrations, having all the fixtures in one directory can get messy. You can use `/` to create folders for your fixtures. + +```php +MockClient::global([ + GetServersRequest::class => MockResponse::fixture('forge/servers'), +]); +``` + +{% hint style="warning" %} +You should be cautious when naming fixture folders - some operating systems like MacOS do not have case sensitivity for folders but some Unix-based systems like Linux do. This can result in fixtures not being found. It's recommended to use lowercase names. +{% endhint %} + +#### Refreshing Fixtures + +If you need to refresh a fixture, all you have to do is delete the JSON file and re-run your test. Saloon will see the file is no longer there and will re-record the request. + +### Testing individual requests and SDKs + +Occasionally, you might want to write unit tests for individual requests to ensure you are sending the right information to an API. If you are building an SDK, then you may wish to follow this guide for testing your SDK. + +#### Using the withMockClient method on your connector + +Instead of using the global mock client, you can create a local instance of a MockClient and pass it into your connector or request using the `withMockClient` method. + +
<?php
+
+test('a request sends the correct body', function () {
+    $mockClient = new MockClient([
+        CreateServerRequest::class => MockResponse::make('Server Created', 200),
+    ]);
+
+    $connector = new ForgeConnector;
+    $connector->withMockClient($mockClient);
+    
+    $connector->send(new CreateServerRequest($name, $ip));
+    
+    $mockClient->assertSent(function (Request $request) {
+        return $request->body()->all() === ['name' => $name, 'ip' => $ip];
+    });
+});
+
+ +### Assertions + +Saloon has a variety of built-in assertion methods which you can also use in your test to assert that Saloon is sending the right information to the third-party API. You can define a variable for your MockClient and call the various assertion methods inside of your test. + +```php + MockResponse::make(...), + ]); + + // Your application code... + + $mockClient->assertSent(GetServersRequest::class); + + $mockClient->assertSentCount(1); +}); +``` + +Saloon has the following assertions: + +#### assertSent / assertNotSent + +These methods will check that a specific request has been sent. + +```php +$mockClient->assertSent(GetServersRequest::class); +``` + +The method can also accept a closure which should return true for more advanced assertions. + +```php +$mockClient->assertSent(function (Request $request, Response $response) { + return $request instanceof GetServersRequest; +}); +``` + +#### assertSentCount + +This method allows you to assert that a specific number of requests has been sent. + +```php +$mockClient->assertSentCount(1); +``` + +The method also accepts a second argument which allows you to check the amount a specific request class was sent. + +```php +$mockClient->assertSentCount(2, GetServersRequest::class); +$mockClient->assertSentCount(1, CreateServerRequest::class); +``` + +#### assertNothingSent + +This method will assert that no requests have been sent. + +```php +$mockClient->assertNothingSent(); +``` + +### Preventing Stray Requests + +You may want to prevent real API calls from being attempted in your tests. You can use `Config::preventStrayRequests()` which will throw an exception if a real API call is attempted. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\Config; + +Config::preventStrayRequests(); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\Config; + +class TestCase extends BaseTestCase +{ + protected function setUp(): void + { + parent::setUp(); + Config::preventStrayRequests(); + } +} +``` +{% endtab %} +{% endtabs %} + +{% hint style="warning" %} +Fixtures will still be recorded and not counted as stray requests. +{% endhint %} + +### Preventing Fixtures Being Recorded + +While running tests, you may wish to prevent Saloon from attempting to record any further fixtures. This is useful for CI like GitHub actions where you shouldn't expect any fixtures to be recorded. You can use `MockConfig::throwOnMissingFixtures()` to prevent this from happening. + +{% tabs %} +{% tab title="PEST" %} +If you are using PEST, then you should add the following code to your `Pest.php` file. + +```php +use Saloon\MockConfig; + +MockConfig::throwOnMissingFixtures(); +``` +{% endtab %} + +{% tab title="PHPUnit" %} +If you are using PHPUnit, then you should add the following line inside of your `setUp` method in your test or application's `TestCase.php` file. + +```php +use Saloon\MockConfig; + +class TestCase extends BaseTestCase +{ + protected function setUp(): void + { + MockConfig::throwOnMissingFixtures(); + } +} +``` +{% endtab %} +{% endtabs %} + +### Redacting Recorded Responses / Fixtures + +When using fixtures to record real responses from an API - sometimes the API will return some sensitive information that you shouldn't store in your application's repository, like names of real people, financial data or emails. With Saloon, you can create a custom fixture class and provide a few methods to obscure the information when the data is stored. You can even provide closures for the data replacement so you can use tools like Faker to replace data like-for-like. + +{% hint style="info" %} +The first time the request is made and the fixture is stored, the original response won't be redacted. Only future requests made with the fixture will use the redacted recording. +{% endhint %} + +First, create a new class in your tests directory and extend the base `Fixture` class provided by Saloon. Next, extend the `defineName` method and give the fixture a name. You can still use slashes in this directory to denote folders. + +Now you can use a few different methods to redact your fixture data. + +* defineSensitiveHeaders for headers +* defineSensitiveJsonParameters for JSON responses +* defineSensitiveRegexPatterns for other body types + +The methods expect a key => value array where the key is the property that is being redacted and the value is the replacement. You can use a string as the replacement or use a closure for more advanced replacement engines like using faker. + +
<?php
+
+namespace Tests\Fixtures\Forge\SingleServerFixture;
+
+use Saloon\Http\Faking\Fixture;
+
+class SingleServerFixture extends Fixture
+{
+    protected function defineName(): string
+    {
+        return 'forge/singleServer';
+    }
+    
+    protected function defineSensitiveHeaders(): array
+    {
+        return [
+            'Authorization' => 'REDACTED',
+        ];
+    }
+
+    protected function defineSensitiveJsonParameters(): array
+    {
+        return [
+            'name' => 'REDACTED',
+            'password' => function () {
+                return faker()->password;
+            },
+        ];
+    }
+    
+    protected function defineSensitiveRegexPatterns(): array
+    {
+        return [
+            '/@[a-z0-9_]{0,100}/' => 'REDACTED-TWITTER-HANDLE',
+        ];
+    } 
+}
+
+ +Once you have created your custom fixture class with the redaction configuration, you can simply use it instead of `MockResponse::fixture()` in your tests. All detection methods in the mock client work with this type of fixture too. + +
<?php
+
+$mockClient = new MockClient([
+    GetServerRequest::class => new SingleServerFixture;
+]);
+
+ +### Using Saloon's Laravel Facade + +If you have installed the [official Laravel plugin](../../installable-plugins/laravel-integration.md), then you can use the `Saloon::fake()` method as an alias of `MockClient::global()`. + +```php +use Saloon\Laravel\Facades\Saloon; + +Saloon::fake([ + GetServersRequest::class => MockResponse::make(body: '', status: 200), +]); +``` + +]]> +
+
+
+ + +High Impact Changes + +High-impact changes will most likely be things that everyone needs to update. + +#### Minimum TLS 1.2 version enforced + +From version three, Saloon uses Guzzle `^7.6` which introduced a new option to configure a minimum TLS version. With Saloon v3, Saloon has set this default to **TLS 1.2.** If any of your API integrations require a lower level of TLS security, you can change the Saloon config while your application is loading. + +```php +FindReplaceuse Saloon\Contracts\Connectoruse Saloon\Http\Connectoruse Saloon\Contracts\Requestuse Saloon\Http\Requestuse Saloon\Contracts\PendingRequestuse Saloon\Http\PendingRequestuse Saloon\Contracts\Responseuse Saloon\Http\Response + +{% hint style="info" %} +There have been many other interfaces removed in v3 however it's unlikely that your application would have used them. They are listed below. +{% endhint %} + +#### HasBody Trait Renamed to HasStringBody + +During some of the code review to improve readability, the `HasBody` body trait has been renamed to `HasStringBody` to be more explicit. If any of your requests send a **plain string body**, you should find and replace this trait. + +
FindReplace
use Saloon\Traits\Body\HasBodyuse Saloon\Traits\Body\HasStringBody
use HasBodyuse HasStringBody
+ +### Medium Impact Changes + +Medium-impact changes are changes that come up for some people but not others. + +#### SendAndRetry method argument name changes + +The second argument of the `$connector->sendAndRetry()` method has been renamed from `maxAttempts` to `tries`. If you are using named arguments then you will need to replace this name. + +
$connector->sendAndRetry(
+    request: $request,
+    tries: 5,
+);
+
+ +#### SendAndRetry handler now expects a Request class and not PendingRequest + +If you previously used the `handleRetry` argument when using `$connector->sendAndRetry()` - Saloon will now send an instance of `Request` instead of `PendingRequest` through the closure. + +
$connector->sendAndRetry(
+    request: $request,
+    tries: 5,
+    interval: 0,
+    handleRetry: static function (Throwable $exception, Request $request) {
+        // $request->headers()->add();
+    },
+);
+
+ +#### Config Method Changes + +With version three, some of the methods in the `Saloon\Config` class have been renamed. These changes have been listed below and you should make sure to rename them if you have used them in your application. + +| Find | Replace | +| ----------------------------- | --------------------------------- | +| `Config::middleware()` | `Config::globalMiddleware()` | +| `Config::resetMiddleware()` | `Config::clearGlobalMiddleware()` | +| `Config::resolveSenderWith()` | `Config::setSenderResolver()` | +| `Config::setDefaultSender()` | `Config::$defaultSender =` | + +### Low Impact Changes + +Low-impact changes are changes that are unlikely to come up unless you have overwritten some of Saloon's functionality or used its interfaces. It's still worth looking through to make sure you haven't missed anything. + +#### Methods Renamed On MockResponse + +On the `MockResponse` class Saloon had a few methods which have now been renamed to be more consistent with the rest of Saloon. These changes are: + +* `getBody()` has changed to `body()` +* `getHeaders()` has changed to `headers()` +* `getStatus()` has changed to `status()` + +#### Middleware Arguments Changed + +Saloon v3 introduced the ability to reorder middleware. With this, the old `prepend` argument on middleware methods has been replaced with a `pipeOrder` argument. Additionally, the second argument for the middleware is now `name` . + +#### Methods Removed From PendingRequest Class + +The following methods have now been removed from the `PendingRequest` class. You can use the suggested replacement if you are using them in your application. + +
OldSuggested Replacement
$pendingRequest->send()$pendingRequest->getConnector()->send()
$pendingRequest->sendAsync()$pendingRequest->getConnector()->sendAsync()
$pendingRequest->getSender()$pendingRequest->getConnector()->sender()
+ +#### Promise Execution Changes + +Previously, Saloon's `PendingRequest` and middleware would be invoked before an asynchronous request was sent (using `$connector->sendAsync()`) - now Saloon has fixed this issue and the `PendingRequest` and middleware will only be invoked while the `Promise` is being resolved - at the same time as sending the request. If your application depended on the old way the middleware was invoked you should make sure your application isn't affected by this change. + +#### SimulatedResponsePayload Class Renamed + +Previously, the `MockResponse` would extend a class called `SimulatedResponsePayload`. This class has now been renamed to `FakeResponse`. Additionally, methods on the `PendingRequest` like `$pendingRequest->setSimulatedResponsePayload()` has been renamed to `$pendingRequest->setFakeResponse()`. If you were extending the old class or using the methods to set the fake response in middleware, you should rename these methods. + +#### Sender Contract Updated + +The `Sender` interface has been completely rewritten in Saloon v3. Instead of just the `sendRequest` method. You now have to define three methods. If you have made a custom sender in Saloon, you should make sure this is updated. + +```php + + +Show Removed Interfaces + +* src/Contracts/Arrayable.php +* src/Contracts/Authenticatable.php +* src/Contracts/CanThrowRequestExceptions.php +* src/Contracts/Connector.php +* src/Contracts/DebuggingDriver.php +* src/Contracts/Dispatcher.php +* src/Contracts/HasConfig.php +* src/Contracts/HasDebugging.php +* src/Contracts/HasDelay.php +* src/Contracts/HasHeaders.php +* src/Contracts/HasMiddlewarePipeline.php +* src/Contracts/HasMockClient.php +* src/Contracts/HasPagination.php +* src/Contracts/HasQueryParams.php +* src/Contracts/IntegerStore.php +* src/Contracts/MiddlewarePipeline.php +* src/Contracts/MockClient.php +* src/Contracts/Paginator.php +* src/Contracts/PendingRequest.php +* src/Contracts/Pipeline.php +* src/Contracts/Pool.php +* src/Contracts/Request.php +* src/Contracts/Response.php +* src/Contracts/SimulatedResponsePayload.php + + + +#### The Base BodyRepository Class Is No Longer Stringable + +If you have made your own `BodyRepository` class from the base class and relied on the `__toString` method this has now been removed. Additionally, the interface has been updated and now requires a `toStream()` method. Inside here, you must define how to convert your body type into a Stream using the provided `StreamFactory`. + +#### Timeout Enum Removed + +The old `Timeout` enum has now been removed. If your application used to use this method, you should migrate to use `Config::$defaultConnectionTimeout` and `Config::$defaultRequestTimeout`. + +#### ToArray Method Removed From MultipartValue + +Previously, the `MultipartValue` object had a `toArray` method. Now that all body repositories are converted into Streams, this method is no longer required. + +#### SimulatedSender Removed + +The `SimulatedSender` class which would be used if you were mocking or had a cached response has now been removed. + +### Did we miss anything? + +If we forgot to add something to this upgrade please let us know by [opening an issue](https://github.com/saloonphp/saloon/issues). + +]]> +
+ + **333 changed files** with **4,063 additions** and **7,576 deletions** + +### Changes in version three + +#### Improved Pagination + +One of the biggest changes is how pagination in Saloon works. After seeing a few people use it - we felt that the developer experience could be better, so we revisited the whole feature. With Saloon v3, it no longer comes bundled into Saloon which reduces code but the pagination plugin provides a beautiful, expressive way to build and customise paginators. + +One of the motivations for rebuilding the pagination was customisation. Previously, you would have to extend the paginator class you are already using and guess which methods needed to be changed. The new pagination has been massively simplified and each of the paginators use the same methods to apply their pagination. This makes them much easier to build and maintain. Here is how the pagination definition looks in version three: + +```php +json('next_page_url')); + } + + // Get page items... + + protected function getPageItems(Response $response, Request $request): array + { + return $response->json('items'); + } + }; + } +} +``` + +#### PSR Support + +Another important change to Saloon v3 was to lean more into the building and use of PSR-7 requests. Previously, Saloon would use Guzzle's configuration options to build up query parameters, request body and the URI. Now, Saloon builds all PSR requests in-house and passes that request to the sender. This provides a few key benefits over letting Guzzle handle it: + +* **Better developer experience** - with less hidden "magic" going on behind the scenes, you'll be able to debug and dump the PSR request Saloon creates to see how your request will be sent and what you're sending. +* **Decoupled further from Guzzle** - Saloon now only uses Guzzle to send your requests which means Saloon is much less dependent on Guzzle. +* **Lower-level customization** - You will be able to modify the PSR-7 request before it is sent, which gives you much better control than before. +* **New PSR methods -** You will now be able to create a PSR-7 request from a `PendingRequest` class. + +{% hint style="info" %} +This is an internal change only, and you won't need to change how your implementation works. You'll still use connectors and requests. +{% endhint %} + +#### Global Retry System + +Another really exciting feature in version three is the ability to configure retrying functionality at a connector level for all of your requests. Previously, the only way to configure the retry functionality was to do it in-line like this: + +```php +$response = $connector->sendAndRetry($request, 5); +``` + +This worked well, but it doesn't really follow one of Saloon's core values - to have beautiful, reusable code. Now you can define retrying at a class level. You just have to add the `$tries` property to either your connector or request to get it to work. After this, if you use `$connector->send()` and the request fails, it will be retried automatically. This is especially useful for SDK development or building against unstable APIs that need retrying at a connector level. + +```php +class ForgeConnector extends Connector +{ + /** + * The number of times a request should be retried if a failure response is returned. + * + * Set to null to disable the retry functionality. + */ + public ?int $tries = 5; +} +``` + +#### New Response Body Methods + +Saloon version three has a few new methods for the `Response` class to make it even easier to use in your application. + +* **saveBodyToFile($pathOrResource)** - This method allows you to save the raw body straight to a file or into an open file resource while keeping memory usage low. +* **getRawStream()** - This method is similar to the existing `stream()` method but will return a file `resource` instead of a `StreamInterface`. This method is really useful when passing the stream into other libraries like League's Flysystem library. +* **getConnector()** - This method is a nice shortcut to get the connector from the response. +* **getPsrRequest()** - This method gives you the PSR request that was built when sending the request - which is the lowest level request class before going through the HTTP client. + +#### Removed Interfaces For Maintainability + +With Saloon v2 - almost every class had an interface that acted as a blueprint for how the class should be structured. This was a decision made in version two to help make Saloon as flexible as possible. With version three, the decision was made to go back on this flexibility. While the added flexibility of giving the developer the freedom to make their own implementations - it added unnecessary complication and blocked Saloon from nice features and methods that could have been added before version three. + +We believe that most Saloon users would just use Saloon's implementation and adequate customization can be achieved with inheritance. + +Many interfaces (contracts) were removed with version three but some of the major ones include: + +* **Saloon\Contracts\Connector** +* **Saloon\Contracts\Request** +* **Saloon\Contracts\PendingRequest** +* **Saloon\Contracts\Response** + +The abstract classes still exist, but without the interfaces - the maintainability of Saloon v3 has improved massively. This means that the current version can be maintained for longer and new features can be released faster and without major version changes. + +#### Minimum TLS 1.2 Security + +Saloon version three requires Guzzle `^7.6` which introduced support for a minimum TLS version. Since TLS 1.1 has been deprecated for almost three years, Saloon has made the minimum version **TLS 1.2**. This is to promote more secure API integrations and follow best practices however it can be changed using configuration if required. + +#### Better Middleware Order + +The previous version introduced support for middleware in Saloon and allowed users to add their own middleware. This also introduced some challenges with how some of Saloon's other features worked like mocking and authenticators. Often when the user adds their own middleware, they may not see headers from authenticators or mock clients being applied to the `PendingRequest` class. Saloon v3's middleware order has been improved for the best feature compatibility. + +If you are curious, this is how the new middleware order looks: + +1. Plugins are "booted" +2. Request and connector properties (Headers, Query Parameters, Config, Middleware) are merged +3. Request and connector body is merged +4. Request and connector delay is merged +5. Authenticators are invoked and their logic applied to the `PendingRequest` +6. Request and connector is "booted" +7. Headers are validated +8. Delay is invoked (if applied) +9. Middleware is run in the following order: + 1. Global middleware + 2. Mock client finds a fake response (if present) + 3. Plugin middleware + 4. **User-added middleware** + 5. Debugging middleware is run (for the final object) + +#### Simplified Debugging + +Saloon v2 shipped with some useful debugging functionality. It came with numerous drivers for different outputs and worked nicely. With version three, it was decided that debugging should be simpler. From version three, if you need to debug your request or response, you can now use the `debug` method and pass in a closure to see either the `PendingRequest` , PSR request or `Response` class while it is being sent. + +Additionally, changes were made to the middleware pipeline to allow the debugging middleware to always run at the end of the pipeline, ensuring you'll always see the final result. + +```php +$connector->debugRequest(static function (PendingRequest $pendingRequest, Requestinterface $psrRequest) { + dd($pendingRequest->headers()); +}); + +$connector->debugResponse(static function (Response $response) { + dd($response->body()); +}); +``` + +#### Better Asynchronous Promise Handling + +With Saloon v3, promises are handled better. Previously, the `PendingRequest` class would be built up, and middleware run and then the `Promise` was created. With version three, a promise is created straight away and the `PendingRequest` and middleware is only invoked when the promise is being sent. This is good for plugins that need to run when a request is being sent like the rate limit plugin. + +#### SDK Helpers + +Last, but not least - Saloon v3 has shipped with a `BaseResource` class which is a class that was recommended in the [Building SDKs](../the-basics/building-sdks.md#request-resources) chapter of the documentation. Since this class is only small and provides value to the SDK developer, this class has now been bundled. + +]]> + +
+
diff --git a/_docs/xml/spatie-laravel-data_docs.xml b/_docs/xml/spatie-laravel-data_docs.xml new file mode 100644 index 0000000..171d25d --- /dev/null +++ b/_docs/xml/spatie-laravel-data_docs.xml @@ -0,0 +1,9081 @@ + + + + + + + + 'Rick Astley', + 'record_company' => 'RCA Records', + 'country field' => 'Belgium', + 'CityName' => 'Antwerp', + 'addressline1' => 'some address line 1', + 'ADDRESSLINE2' => 'some address line 2', +]); +``` + +When transforming such a data object the payload will look like this: + +```json +{ + "name" : "Rick Astley", + "record_company" : "RCA Records", + "country field" : "Belgium", + "CityName" : "Antwerp", + "addressline1" : "some address line 1", + "ADDRESSLINE2" : "some address line 2" +} +``` + +]]> + + + [ + /* + * Provides default configuration for the `make:data` command. These settings can be overridden with options + * passed directly to the `make:data` command for generating single Data classes, or if not set they will + * automatically fall back to these defaults. See `php artisan make:data --help` for more information + */ + 'make' => [ + /* + * The default namespace for generated Data classes. This exists under the application's root namespace, + * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the + * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. + */ + 'namespace' => 'Data', + + /* + * This suffix will be appended to all data classes generated by make:data, so that they are less likely + * to conflict with other related classes, controllers or models with a similar name without resorting + * to adding an alias for the Data object. Set to a blank string (not null) to disable. + */ + 'suffix' => 'Data', + ], +] +``` + +]]> + + +type` to get the type the items should be transformed into. + +## Combining casts and transformers + +You can combine casts and transformers in one class: + +```php +class ToUpperCastAndTransformer implements Cast, Transformer +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): string + { + return strtoupper($value); + } + + public function transform(DataProperty $property, mixed $value, TransformationContext $context): string + { + return strtoupper($value); + } +} +``` + +Within your data object, you can use the `WithCastAndTransformer` attribute to use the cast and transformer: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[WithCastAndTransformer(SomeCastAndTransformer::class)] + public string $artist, + ) { + } +} +``` + +]]> + + +add(new Min(42)); +``` + +When adding a rule of the same kind, a previous version of the rule will be removed: + +```php +$rules->add(new Min(42)); +$rules->add(new Min(314)); + +$rules->all(); // [new Min(314)] +``` + +Adding a string rule can be done as such: + +```php +$rules->add(new Rule('min:42')); +``` + +You can check if the collection contains a type of rule: + +```php +$rules->hasType(Min::class); +``` + +Or remove certain types of rules: + +```php +$rules->removeType(Min::class); +``` + +In the end, a rule inferrer should always return a `RulesCollection`. + +Rule inferrers need to be manually defined within the `data.php` config file. + + +]]> + + + + + + ArtistData::class, + ]; +} +``` + +Now you can store a data object in a model as such: + +```php +Song::create([ + 'artist' => new ArtistData(name: 'Rick Astley', age: 22), +]); +``` + +It is also possible to use an array representation of the data object: + +```php +Song::create([ + 'artist' => [ + 'name' => 'Rick Astley', + 'age' => 22 + ] +]); +``` + +This will internally be converted to a data object which you can later retrieve as such: + +```php +Song::findOrFail($id)->artist; // ArtistData object +``` + +### Abstract data objects + +Sometimes you have an abstract parent data object with multiple child data objects, for example: + +```php +abstract class RecordConfig extends Data +{ + public function __construct( + public int $tracks, + ) {} +} + +class CdRecordConfig extends RecordConfig +{ + public function __construct( + int $tracks, + public int $bytes, + ) { + parent::__construct($tracks); + } +} + +class VinylRecordConfig extends RecordConfig +{ + public function __construct( + int $tracks, + public int $rpm, + ) { + parent::__construct($tracks); + } +} +``` + +A model can have a JSON field which is either one of these data objects: + +```php +class Record extends Model +{ + protected $casts = [ + 'config' => RecordConfig::class, + ]; +} +``` + +You can then store either a `CdRecordConfig` or a `VinylRecord` in the `config` field: + +```php +$cdRecord = Record::create([ + 'config' => new CdRecordConfig(tracks: 12, bytes: 1000), +]); + +$vinylRecord = Record::create([ + 'config' => new VinylRecordConfig(tracks: 12, rpm: 33), +]); + +$cdRecord->config; // CdRecordConfig object +$vinylRecord->config; // VinylRecordConfig object +``` + +When a data object class is abstract and used as an Eloquent cast, then this feature will work out of the box. + +The child data object value of the model will be stored in the database as a JSON string with the class name and the data object properties: + +```json +{ + "type": "\\App\\Data\\CdRecordConfig", + "data": { + "tracks": 12, + "bytes": 1000 + } +} +``` + +When retrieving the model, the data object will be instantiated based on the `type` key in the JSON string. + +#### Abstract data object with collection + +You can use with collection. + +```php +class Record extends Model +{ + protected $casts = [ + 'configs' => DataCollection::class . ':' . RecordConfig::class, + ]; +} +``` + +#### Abstract data class morphs + +By default, the `type` key in the JSON string will be the fully qualified class name of the child data object. This can break your application quite easily when you refactor your code. To prevent this, you can add a morph map like with [Eloquent models](https://laravel.com/docs/eloquent-relationships#polymorphic-relationships). Within your `AppServiceProvivder` you can add the following mapping: + +```php +use Spatie\LaravelData\Support\DataConfig; + +app(DataConfig::class)->enforceMorphMap([ + 'cd_record_config' => CdRecordConfig::class, + 'vinyl_record_config' => VinylRecordConfig::class, +]); +``` + +## Casting data collections + +It is also possible to store data collections in an Eloquent model: + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class, + ]; +} +``` + +A collection of data objects within the Eloquent model can be made as such: + +```php +Artist::create([ + 'songs' => [ + new SongData(title: 'Never gonna give you up', artist: 'Rick Astley'), + new SongData(title: 'Together Forever', artist: 'Rick Astley'), + ], +]); +``` + +It is also possible to provide an array instead of a data object to the collection: + +```php +Artist::create([ + 'songs' => [ + ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley'], + ['title' => 'Together Forever', 'artist' => 'Rick Astley'] + ], +]); +``` + +## Using defaults for null database values + +By default, if a database value is `null`, then the model attribute will also be `null`. However, sometimes you might want to instantiate the attribute with some default values. + +To achieve this, you may provide an additional `default` [Cast Parameter](https://laravel.com/docs/eloquent-mutators#cast-parameters) to ensure the caster gets instantiated. + +```php +class Song extends Model +{ + protected $casts = [ + 'artist' => ArtistData::class . ':default', + ]; +} +``` + +This will ensure that the `ArtistData` caster is instantiated even when the `artist` attribute in the database is `null`. + +You may then specify some default values in the cast which will be used instead. + +```php +class ArtistData extends Data +{ + public string $name = 'Default name'; +} +``` + +```php +Song::findOrFail($id)->artist->name; // 'Default name' +``` + +### Nullable collections + +You can also use the `default` argument in the case where you _always_ want a `DataCollection` to be returned. + +The first argument (after `:`) should always be the data class to be used with the `DataCollection`, but you can add `default` as a comma separated second argument. + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class.',default', + ]; +} +``` + +```php +$artist = Artist::create([ + 'songs' => null +]); + +$artist->songs; // DataCollection +$artist->songs->count();// 0 +``` + +## Using encryption with data objects and collections + +Similar to Laravel's native encrypted casts, you can also encrypt data objects and collections. + +When retrieving the model, the data object will be decrypted automatically. + +```php +class Artist extends Model +{ + protected $casts = [ + 'songs' => DataCollection::class.':'.SongData::class.',encrypted', + ]; +} +``` + +]]> + + +getData(); // A SongData object +``` + +We can do the same with a FormRequest, we don't use a property here to define the data class but use a method instead: + +```php +class SongRequest extends FormRequest +{ + use WithData; + + protected function dataClass(): string + { + return SongData::class; + } +} +``` + +Now within a controller where the request is injected, we can get the data object like this: + +```php +class SongController +{ + public function __invoke(SongRequest $request): SongData + { + $data = $request->getData(); + + $song = Song::create($data->toArray()); + + return $data; + } +} +``` + +]]> + +<_index_md> + + + + + + + + + + 'required', // Use the original name when defining validation rules + ]; + } + + // ... + } + ``` + +When creating a data object: + +```php +UserData::from([ + 'favorite_song' => ..., // You can use the mapped or original name here + 'title' => 'some title' +]); +``` + +When adding an include, exclude, except or only: + +```php + UserData::from(User::first())->except('song'); // Always use the original name here +``` + +Within a request query, you can use the mapped or original name: + +``` +https://spatie.be/my-account?except[]=favorite_song +``` + +When validating a data object or getting rules for a data object, always use the original name: + +```php +$data = [ + 'favorite_song' => 123, + 'title' => 'some title', +]; + +UserData::validate($data) +UserData::getValidationRules($data) +``` + + +]]> + + +toArray(); + } +} +``` + +Normalizers are executed in the same order as they are defined in the `normalize` method. The first normalizer not returning null will be used to normalize the payload. Magical creation methods always have precedence over normalizers. + +]]> + + + [ + 'cache' => [ + 'store' => 'redis', + 'prefix' => 'laravel-data', + ], +], +``` + +To find the data classes within your application, we're using the [php-structure-discoverer](https://github.com/spatie/php-structure-discoverer) package. This package allows you to configure the directories that will be searched for data objects. By default, the `app/data` directory is searched recursively. You can change this to any other directory or directories: + +```php +'structure_caching' => [ + 'directories' => [ + app_path('Data'), + ], +], +``` + +Structure discoverer uses reflection (enabled by default) or a PHP parser to find the data objects. You can disable the reflection-based discovery and thus use the PHP parser discovery as such: + +```php +'structure_caching' => [ + 'reflection_discovery' => [ + 'enabled' => false, + ], +], +``` + +Since we cannot depend on reflection, we need to tell the parser what data objects are exactly and where to find them. This can be done by adding the laravel-data directory to the config directories: + +```php +'structure_caching' => [ + 'directories' => [ + app_path('Data'), + base_path('vendor/spatie/laravel-data/src'), + ], +], +``` + +When using reflection discovery, the base directory and root namespace can be configured as such if you're using a non-standard directory structure or namespace + +```php +'structure_caching' => [ + 'reflection_discovery' => [ + 'enabled' => true, + 'base_path' => base_path(), + 'root_namespace' => null, + ], +], +``` + +The caching mechanism can be disabled by setting the `enabled` option to `false`: + +```php +'structure_caching' => [ + 'enabled' => false, +], +``` + +You can read more about reflection discovery [here](https://github.com/spatie/php-structure-discoverer#parsers). + +## Testing + +When running tests, the cache is automatically disabled. This ensures that the analysis results are always up-to-date during development and testing. And that the cache won't interfere with your caching mocks. + +]]> + + +into(static::class) + ->through(AuthorizedDataPipe::class) + ->through(MapPropertiesDataPipe::class) + ->through(FillRouteParameterPropertiesDataPipe::class) + ->through(ValidatePropertiesDataPipe::class) + ->through(DefaultValuesDataPipe::class) + ->through(CastPropertiesDataPipe::class); + } +} +``` + +Each pipe implements the `DataPipe` interface and should return an `array` of properties: + +```php +interface DataPipe +{ + public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array; +} +``` + +The `handle` method has several arguments: + +- **payload** the non normalized payload +- **class** the `DataClass` object for the data + object [more info](/docs/laravel-data/v4/advanced-usage/internal-structures) +- **properties** the key-value properties which will be used to construct the data object +- **creationContext** the context in which the data object is being created you'll find the following info here: + - **dataClass** the data class which is being created + - **validationStrategy** the validation strategy which is being used + - **mapPropertyNames** whether property names should be mapped + - **disableMagicalCreation** whether to use the magical creation methods or not + - **ignoredMagicalMethods** the magical methods which are ignored + - **casts** a collection of global casts + +When using a magic creation methods, the pipeline is not being used (since you manually overwrite how a data object is +constructed). Only when you pass in a request object a minimal version of the pipeline is used to authorize and validate +the request. + +## Preparing data for the pipeline + +Sometimes you need to make some changes to the payload after it has been normalized, but before they are sent into the data pipeline. You can do this using the `prepareForPipeline` method as follows: + +```php +class SongMetadata +{ + public function __construct( + public string $releaseYear, + public string $producer, + ) {} +} + +class SongData extends Data +{ + public function __construct( + public string $title, + public SongMetadata $metadata, + ) {} + + public static function prepareForPipeline(array $properties): array + { + $properties['metadata'] = Arr::only($properties, ['release_year', 'producer']); + + return $properties; + } +} +``` + +Now it is possible to create a data object as follows: + +```php +$songData = SongData::from([ + 'title' => 'Never gonna give you up', + 'release_year' => '1987', + 'producer' => 'Stock Aitken Waterman', +]); +``` + +## Extending the pipeline within your data class + +Sometimes you want to send your payload first through a certain pipe without creating a whole new pipeline, this can be done as such: + +```php +class SongData extends Data +{ + public static function pipeline(): DataPipeline + { + return parent::pipeline()->firstThrough(GuessCasingForKeyDataPipe::class); + } +} +``` + +]]> + + + + + +; + lazy? : string; + optional? : string; + simpleData: SimpleData; + dataCollection: Array; +} +``` + +## Installation of extra package + +First, you must install the spatie/laravel-typescript-transformer into your project. + +```bash +composer require spatie/laravel-typescript-transformer +``` + +Next, publish the config file of the typescript-transformer package with: + +```bash +php artisan vendor:publish --tag=typescript-transformer-config +``` + +Finally, add the `Spatie\LaravelData\Support\TypeScriptTransformer\DataTypeScriptTransformer` transformer to the +transformers in the `typescript-transformer.php` config file. + +If you're using the `DtoTransformer` provided by the package, then be sure to put the `DataTypeScriptTransformer` before the `DtoTransformer`. + +## Usage + +Annotate each data object that you want to transform to Typescript with a `/** @typescript */` annotation or +a `#[TypeScript]` attribute. + +To [generate the typescript file](https://spatie.be/docs/typescript-transformer/v4/laravel/executing-the-transform-command) +, run this command: + +```php +php artisan typescript:transform +``` + +If you want to transform all the data objects within your application to TypeScript, you can use +the `DataTypeScriptCollector`, which should be added to the collectors in `typescript-transformer.php`. + +If you're using the `DefaultCollector` provided by the package, then be sure to put the `DataTypeScriptCollector` before the `DefaultCollector`. + +### Optional types + +An optional or lazy property will automatically be transformed into an optional type within TypeScript: + +```php +class DataObject extends Data +{ + public function __construct( + public Lazy|string $lazy, + public Optional|string $optional, + ) + { + } +} +``` + +This will be transformed into: + +```tsx +{ + lazy? : string; + optional? : string; +} +``` + +If you want to have optional typed properties in TypeScript without typing your properties optional or lazy within PHP, +then you can use the `Optional` attribute from the `typescript-transformer` package. + +Don't forget to alias it as `TypeScriptOptional` when you're already using this package's `Optional` type! + +```php +use Spatie\TypeScriptTransformer\Attributes\Optional as TypeScriptOptional; + +class DataObject extends Data +{ + public function __construct( + #[TypeScriptOptional] + public int $id, + public string $someString, + public Optional|string $optional, + ) + { + } +} +``` + +]]> + + + Inertia.js lets you quickly build modern single-page React, Vue, and Svelte apps using classic server-side routing and +> controllers. + +Laravel Data works excellent with [Inertia](https://inertiajs.com). + +You can pass a complete data object to an Inertia response: + +```php +return Inertia::render('Song', SongsData::from($song)); +``` + +## Lazy properties + +This package supports [lazy](https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties) properties, which can +be manually included or excluded. + +Inertia has a similar concept called [lazy data evaluation](https://inertiajs.com/partial-reloads#lazy-data-evaluation), +where some properties wrapped in a closure only get evaluated and included in the response when explicitly asked. +Inertia v2 introduced the concept of [deferred props](https://inertiajs.com/deferred-props), which allows to defer the +loading of certain data until after the initial page render. + +This package can output specific properties as Inertia lazy or deferred props as such: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + public Lazy|string $lyrics, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::inertia(fn() => $song->title), + Lazy::closure(fn() => $song->artist) + Lazy::inertiaDeferred(fn() => $song->lyrics) + ); + } +} +``` + +We provide three kinds of lazy properties: + +- **Lazy::inertia()** Never included on first visit, optionally included on partial reloads +- **Lazy::closure()** Always included on first visit, optionally included on partial reloads +- **Lazy::inertiaDeferred()** Included when ready, optionally included on partial reloads + +Now within your JavaScript code, you can include the properties as such: + +```js +router.reload((url, { + only: ['title'], +}); +``` + +#### Deferred property groups + +It is possible to group deferred properties together, so that all grouped properties are loaded at the same time. In +order to achieve this, you can pass a group name as the second argument to `Lazy::inertiaDeferred()`: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + public Lazy|string $lyrics, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::inertiaDeferred(fn() => $song->title), + Lazy::inertiaDeferred(fn() => $song->artist, 'details') + Lazy::inertiaDeferred(fn() => $song->lyrics, 'details') + ); + } +} +``` + +### Auto lazy Inertia properties + +We already saw earlier that the package can automatically make properties Lazy, the same can be done for Inertia +properties. + +It is possible to rewrite the previous example as follows: + +```php +use Spatie\LaravelData\Attributes\AutoClosureLazy; +use Spatie\LaravelData\Attributes\AutoInertiaLazy; +use Spatie\LaravelData\Attributes\AutoInertiaDeferred; + +class SongData extends Data +{ + public function __construct( + #[AutoInertiaLazy] + public Lazy|string $title, + #[AutoClosureLazy] + public Lazy|string $artist, + #[AutoInertiaDeferred] + public Lazy|string $lyrics, + ) { + } +} +``` + +If all the properties of a class should be either Inertia or closure lazy, you can use the attributes on the class +level: + +```php +#[AutoInertiaLazy] +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + ) { + } +} +``` + +#### Deferred property groups + +For the `AutoInertiaDeferred` attribute, it is also possible to specify a group name in order to group deferred +properties together: + +```php +class SongData extends Data +{ + public function __construct( + #[AutoInertiaDeferred()] + public Lazy|string $title, + #[AutoInertiaDeferred('details')] + public Lazy|string $artist, + #[AutoInertiaDeferred('details')] + public Lazy|string $lyrics, + ) { + } +} +``` + +]]> + + + Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple without leaving the +> comfort of Laravel. + +Laravel Data works excellently with [Laravel Livewire](https://laravel-livewire.com). + +You can use a data object as one of the properties of your Livewire component as such: + +```php +class Song extends Component +{ + public SongData $song; + + public function mount(int $id) + { + $this->song = SongData::from(Song::findOrFail($id)); + } + + public function render() + { + return view('livewire.song'); + } +} +``` + +A few things are required to make this work: + +1) You should implement `Wireable` on all the data classes you'll be using with Livewire +2) Each of these classes should also use the `WireableData` trait provided by this package +3) That's it + +We can update our previous example to make it work with Livewire as such: + +```php +class SongData extends Data implements Wireable +{ + use WireableData; + + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +## Livewire Synths (Experimental) + +Laravel Data also provides a way to use Livewire Synths with your data objects. It will allow you to use data objects +and collections +without the need to make them Wireable. This is an experimental feature and is subject to change. + +You can enable this feature by setting the config option in `data.php`: + +```php +'livewire' => [ + 'enable_synths' => false, +] +``` + +Once enabled, you can use data objects within your Livewire components without the need to make them Wireable: + +```php +class SongUpdateComponent extends Component +{ + public SongData $data; + + public function mount(public int $id): void + { + $this->data = SongData::from(Song::findOrFail($id)); + } + + public function save(): void + { + Artist::findOrFail($this->id)->update($this->data->toArray()); + } + + public function render(): string + { + return <<<'BLADE' +
+

Songs

+ + +

Title: {{ $data->title }}

+

Artist: {{ $data->artist }}

+ +
+ BLADE; + } +} +``` + +### Lazy + +It is possible to use Lazy properties, these properties will not be sent over the wire unless they're included. **Always +include properties permanently** because a data object is being transformed and then cast again between Livewire +requests the includes should be permanent. + +It is possible to query lazy nested data objects, it is however not possible to query lazy properties which are not a data: + +```php +use Spatie\LaravelData\Lazy; + +class LazySongData extends Data +{ + public function __construct( + public Lazy|ArtistData $artist, + public Lazy|string $title, + ) {} +} +``` + +Within your Livewire view + +```php +$this->data->artist->name; // Works +$this->data->title; // Does not work +``` + +### Validation + +Laravel data **does not provide validation** when using Livewire, you should do this yourself! This is because laravel-data +does not support object validation at the moment. Only validating payloads which eventually become data objects. +The validation could technically happen when hydrating the data object, but this is not implemented +because we cannot guarantee that every hydration happens when a user made sure the data is valid +and thus the payload should be validated. + +]]> +
+ + + + + DATE_ATOM, +``` + +Now when using the `DateTimeInterfaceCast` or `DateTimeInterfaceTransformer` the format defined will be used + +```php +#[WithCast(DateTimeInterfaceCast::class)] +#[WithTransformer(DateTimeInterfaceTransformer::class)] +public DateTime $date +``` + +It is also possible to manually set the format; + +```php +#[WithCast(DateTimeInterfaceCast::class, format: DATE_ATOM)] +#[WithTransformer(DateTimeInterfaceTransformer::class, format: DATE_ATOM)] +public DateTime $date +``` + +When casting the data object will use the type of the property to cast a date string into, so if you want to +use `Carbon`, that's perfectly possible: + +```php +#[WithCast(DateTimeInterfaceCast::class)] +public Carbon $date +``` + +You can even manually specify the type the date string should be cast to: + +```php + +#[WithCast(DateTimeInterfaceCast::class, type: CarbonImmutable::class)] +public $date +``` + +## Multiple date formats + +Sometimes your application might use different date formats, for example, you receive dates from an IOS and React +application. These use different underlying date formats. In such case you can add an array to the `date_format` key +within the `data.php` config file: + +```php + 'date_format' => [DATE_ATOM, 'Y-m-d'], +``` + +Now when casting a date, a valid format will be searched. When none can be found, an exception is thrown. + +When a transformers hasn't explicitly stated its format, the first format within the array is used. + +## Casting dates in a different time zone + +Sometimes a date can be in a different timezone than the timezone you application uses. For example, if your application uses `Europe/Brussels` but your date is in `UTC`: + +```php +#[WithCast(DateTimeInterfaceCast::class, timeZone: 'UTC')] +public DateTime $date +``` + +The date will be created with the `UTC` timezone but will be the same as in the `Europe/Brussels` timezone. + +## Changing time zones + +When casting a date you may want to set an alternative timezone this can be achieved as such: + +```php +#[WithCast(DateTimeInterfaceCast::class, setTimeZone: 'Europe/Brussels')] +public DateTime $date +``` + +In this case the time will be transformed, if our original time was in `UTC` then one or two hours (depending on summer time) will be added. + +You can also change the timezone of a property which is getting transformed: + +```php +#[WithTransformer(DateTimeInterfaceTransformer::class, setTimeZone: 'Europe/Brussels')] +public DateTime $date +``` + +]]> + +
+ + + 'Rick Astley', 'voice' => 'tenor']); +Musician::from(['name' => 'Rick Astley', 'instrument' => 'guitar']); +``` + +But what if you want to use this abstract type in another data class like this: + +```php +class Contract extends Data +{ + public string $label; + public Person $artist; +} +``` + +While the following may both be valid: + +```php +Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'voice' => 'tenor']]); +Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'instrument' => 'guitar']]); +``` + +The package can't decide which subclass to construct for the property. + +You can implement the `PropertyMorphableData` interface on the abstract class to solve this. This interface adds a `morph` method that will be used to determine which subclass to use. The `morph` method receives an array of properties limited to properties tagged by a `PropertyForMorph` attribute. + +```php +use Spatie\LaravelData\Attributes\PropertyForMorph; +use Spatie\LaravelData\Contracts\PropertyMorphableData; + +abstract class Person extends Data implements PropertyMorphableData +{ + #[PropertyForMorph] + public string $type; + + public string $name; + + public static function morph(array $properties): ?string + { + return match ($properties['type']) { + 'singer' => Singer::class, + 'musician' => Musician::class, + default => null + }; + } +} +``` + +The example above will work by adding this code, and the correct Data class will be constructed. + +Since the morph functionality needs to run early within the data construction process, it bypasses the normal flow of constructing data objects so there are a few limitations: + +- it is only allowed to use properties typed as string, int, or BackedEnum(int or string) +- When a property is typed as an enum, the value passed to the morph method will be an enum +- it can be that the value of a property within the morph method is null or a different type than expected since it runs before validation +- properties with mapped property names are still supported + +It is also possible to use abstract data classes as collections as such: + +```php +class Band extends Data +{ + public string $name; + + /** @var array */ + public array $members; +} +``` + +]]> + + + 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'date' => '27-07-1987', + 'format' => 'vinyl', +]); +``` + +And get an error because the first two properties are simple PHP types(strings, ints, floats, booleans, arrays), but the following two properties are more complex types: `DateTime` and `Enum`, respectively. + +These types cannot be automatically created. A cast is needed to construct them from a string. + +There are two types of casts, local and global casts. + +## Local casts + +Local casts are defined within the data object itself and can be added using attributes: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + #[WithCast(DateTimeInterfaceCast::class)] + public DateTime $date, + #[WithCast(EnumCast::class)] + public Format $format, + ) { + } +} +``` + +Now it is possible to create a data object like this without exceptions: + +```php +SongData::from([ + 'title' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'date' => '27-07-1987', + 'format' => 'vinyl', +]); +``` + +It is possible to provide parameters to the casts like this: + +```php +#[WithCast(EnumCast::class, type: Format::class)] +public Format $format +``` + +## Global casts + +Global casts are not defined on the data object but in your `data.php` config file: + +```php +'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, +], +``` + +When the data object can find no local cast for the property, the package will look through the global casts and tries to find a suitable cast. You can define casts for: + +- a **specific implementation** (e.g. CarbonImmutable) +- an **interface** (e.g. DateTimeInterface) +- a **base class** (e.g. Enum) + +As you can see, the package by default already provides a `DateTimeInterface` cast, this means we can update our data object like this: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + public DateTime $date, + #[WithCast(EnumCast::class)] + public Format $format, + ) { + } +} +``` + +Tip: we can also remove the `EnumCast` since the package will automatically cast enums because they're a native PHP type, but this made the example easy to understand. + +## Creating your own casts + +It is possible to create your casts. You can read more about this in the [advanced chapter](/docs/laravel-data/v4/advanced-usage/creating-a-cast). + +## Casting arrays or collections of non-data types + +We've already seen how collections of data can be made of data objects, the same is true for all other types if correctly +typed. + +Let say we have an array of DateTime objects: + +```php +class ReleaseData extends Data +{ + public string $title; + /** @var array */ + public array $releaseDates; +} +``` + +By enabling the `cast_and_transform_iterables` feature in the `data` config file (this feature will be enabled by default in laravel-data v5): + +```php +'features' => [ + 'cast_and_transform_iterables' => true, +], +``` + +We now can create a `ReleaseData` object with an array of strings which will be cast into an array DateTime objects: + +```php +ReleaseData::from([ + 'title' => 'Never Gonna Give You Up', + 'releaseDates' => [ + '1987-07-27T12:00:00Z', + '1987-07-28T12:00:00Z', + '1987-07-29T12:00:00Z', + ], +]); +``` + +For this feature to work, a cast should not only implement the `Cast` interface but also the `IterableItemCast`. The +signatures of the `cast` and `castIterableItem` methods are exactly the same, but they're called on different times. +When casting a property like a DateTime from a string, the `cast` method will be used, when transforming an iterable +property like an array or Laravel Collection where the iterable item is typed using an annotation, then each item of the +provided iterable will trigger a call to the `castIterableItem` method. + +]]> + + + 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'], +]); // returns an array of SongData objects +``` + +Whatever type of collection you pass in, the package will return the same type of collection with the freshly created +data objects within it. As long as this type is an array, Laravel collection or paginator or a class extending from it. + +This opens up possibilities to create collections of Eloquent models: + +```php +SongData::collect(Song::all()); // return an Eloquent collection of SongData objects +``` + +Or use a paginator: + +```php +SongData::collect(Song::paginate()); // return a LengthAwarePaginator of SongData objects + +// or + +SongData::collect(Song::cursorPaginate()); // return a CursorPaginator of SongData objects +``` + +Internally the `from` method of the data class will be used to create a new data object for each item in the collection. + +When the collection already contains data objects, the `collect` method will return the same collection: + +```php +SongData::collect([ + SongData::from(['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley']), + SongData::from(['title' => 'Giving Up on Love', 'artist' => 'Rick Astley']), +]); // returns an array of SongData objects +``` + +The collect method also allows you to cast collections from one type into another. For example, you can pass in +an `array`and get back a Laravel collection: + +```php +SongData::collect($songs, Collection::class); // returns a Laravel collection of SongData objects +``` + +This transformation will only work with non-paginator collections. + +## Magically creating collections + +We've already seen that `from` can create data objects magically. It is also possible to create a collection of data +objects magically when using `collect`. + +Let's say you've implemented a custom collection class called `SongCollection`: + +```php +class SongCollection extends Collection +{ + public function __construct( + $items = [], + public array $artists = [], + ) { + parent::__construct($items); + } +} +``` + +Since the constructor of this collection requires an extra property it cannot be created automatically. However, it is +possible to define a custom collect method which can create it: + +```php +class SongData extends Data +{ + public string $title; + public string $artist; + + public static function collectArray(array $items): SongCollection + { + return new SongCollection( + parent::collect($items), + array_unique(array_map(fn(SongData $song) => $song->artist, $items)) + ); + } +} +``` + +Now when collecting an array data objects a `SongCollection` will be returned: + +```php +SongData::collectArray([ + ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Living on a prayer', 'artist' => 'Bon Jovi'], +]); // returns an SongCollection of SongData objects +``` + +There are a few requirements for this to work: + +- The method must be **static** +- The method must be **public** +- The method must have a **return type** +- The method name must **start with collect** +- The method name must not be **collect** + +## Creating a data object with collections + +You can create a data object with a collection of data objects just like you would create a data object with a nested +data object: + +```php +use App\Data\SongData; +use Illuminate\Support\Collection; + +class AlbumData extends Data +{ + public string $title; + /** @var Collection */ + public Collection $songs; +} + +AlbumData::from([ + 'title' => 'Never Gonna Give You Up', + 'songs' => [ + ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], + ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'], + ] +]); +``` + +Since the collection type here is a `Collection`, the package will automatically convert the array into a collection of +data objects. + +## DataCollections, PaginatedDataCollections and CursorPaginatedCollections + +The package also provides a few collection classes which can be used to create collections of data objects. It was a +requirement to use these classes in the past versions of the package when nesting data objects collections in data +objects. This is no longer the case, but there are still valid use cases for them. + +You can create a DataCollection like this: + +```php +use Spatie\LaravelData\DataCollection; + +SongData::collect(Song::all(), DataCollection::class); +``` + +A PaginatedDataCollection can be created like this: + +```php +use Spatie\LaravelData\PaginatedDataCollection; + +SongData::collect(Song::paginate(), PaginatedDataCollection::class); +```` + +And a CursorPaginatedCollection can be created like this: + +```php +use Spatie\LaravelData\CursorPaginatedCollection; + +SongData::collect(Song::cursorPaginate(), CursorPaginatedCollection::class); +``` + +### Why using these collection classes? + +We advise you to always use arrays, Laravel collections and paginators within your data objects. But let's say you have +a controller like this: + +```php +class SongController +{ + public function index() + { + return SongData::collect(Song::all()); + } +} +``` + +In the next chapters of this documentation, we'll see that it is possible to include or exclude properties from the data +objects like this: + +```php +class SongController +{ + public function index() + { + return SongData::collect(Song::all(), DataCollection::class)->include('artist'); + } +} +``` + +This will only work when you're using a `DataCollection`, `PaginatedDataCollection` or `CursorPaginatedCollection`. + +### DataCollections + +DataCollections provide some extra functionalities like: + +```php +// Counting the amount of items in the collection +count($collection); + +// Changing an item in the collection +$collection[0]->title = 'Giving Up on Love'; + +// Adding an item to the collection +$collection[] = SongData::from(['title' => 'Never Knew Love', 'artist' => 'Rick Astley']); + +// Removing an item from the collection +unset($collection[0]); +``` + +It is even possible to loop over it with a foreach: + +```php +foreach ($songs as $song){ + echo $song->title; +} +``` + +The `DataCollection` class implements a few of the Laravel collection methods: + +- through +- map +- filter +- first +- each +- values +- where +- reduce +- sole + +You can, for example, get the first item within a collection like this: + +```php +SongData::collect(Song::all(), DataCollection::class)->first(); // SongData object +``` + +### The `collection` method + +In previous versions of the package it was possible to use the `collection` method to create a collection of data +objects: + +```php +SongData::collection(Song::all()); // returns a DataCollection of SongData objects +SongData::collection(Song::paginate()); // returns a PaginatedDataCollection of SongData objects +SongData::collection(Song::cursorPaginate()); // returns a CursorPaginatedCollection of SongData objects +``` + +This method was removed with version v4 of the package in favor for the more powerful `collect` method. The `collection` +method can still be used by using the `WithDeprecatedCollectionMethod` trait: + +```php +use Spatie\LaravelData\Concerns\WithDeprecatedCollectionMethod; + +class SongData extends Data +{ + use WithDeprecatedCollectionMethod; + + // ... +} +``` + +Please note that this trait will be removed in the next major version of the package. + +]]> + + +full_name = "{$this->first_name} {$this->last_name}"; + } +} +``` + +You can now do the following: + +```php +SongData::from(['first_name' => 'Ruben', 'last_name' => 'Van Assche']); +``` + +Please notice: the computed property won't be reevaluated when its dependencies change. If you want to update a computed property, you'll have to create a new object. + +Again there are a few conditions for this approach: + +- You must always use a sole property, a property within the constructor definition won't work +- Computed properties cannot be defined in the payload, a `CannotSetComputedValue` will be thrown if this is the case +- If the `ignore_exception_when_trying_to_set_computed_property_value` configuration option is set to `true`, the computed property will be silently ignored when trying to set it in the payload and no `CannotSetComputedValue` exception will be thrown. + + +]]> + + + 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +You can use the `from` method to create a data object from nearly anything. For example, let's say you have an Eloquent +model like this: + +```php +class Song extends Model +{ + // Your model code +} +``` + +You can create a data object from such a model like this: + +```php +SongData::from(Song::firstOrFail($id)); +``` + +The package will find the required properties within the model and use them to construct the data object. + +Data can also be created from JSON strings: + +```php +SongData::from('{"title" : "Never Gonna Give You Up","artist" : "Rick Astley"}'); +``` + +Although the PHP 8.0 constructor properties look great in data objects, it is perfectly valid to use regular properties +without a constructor like so: + +```php +class SongData extends Data +{ + public string $title; + public string $artist; +} +``` + +## Magical creation + +It is possible to overwrite or extend the behaviour of the `from` method for specific types. So you can construct a data +object in a specific manner for that type. This can be done by adding a static method starting with 'from' to the data +object. + +For example, we want to change how we create a data object from a model. We can add a `fromModel` static method that +takes the model we want to use as a parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromModel(Song $song): self + { + return new self("{$song->title} ({$song->year})", $song->artist); + } +} +``` + +Now when creating a data object from a model like this: + +```php +SongData::from(Song::firstOrFail($id)); +``` + +Instead of the default method, the `fromModel` method will be called to create a data object from the found model. + +You're truly free to add as many from methods as you want. For example, you could add one to create a data object from a +string: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromString(string $string): self + { + [$title, $artist] = explode('|', $string); + + return new self($title, $artist); + } +} +``` + +From now on, you can create a data object like this: + +```php +SongData::from('Never gonna give you up|Rick Astley'); +``` + +It is also possible to use multiple arguments in a magical creation method: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromMultiple(string $title, string $artist): self + { + return new self($title, $artist); + } +} +``` + +Now we can create the data object like this: + +```php +SongData::from('Never gonna give you up', 'Rick Astley'); +``` + +There are a few requirements to enable magical data object creation: + +- The method must be **static and public** +- The method must **start with from** +- The method cannot be called **from** + +When the package cannot find such a method for a type given to the data object's `from` method. Then the data object +will try to create itself from the following types: + +- An *Eloquent model* by calling `toArray` on it +- A *Laravel request* by calling `all` on it +- An *Arrayable* by calling `toArray` on it +- An *array* + +This list can be extended using extra normalizers, find more about +it [here](/docs/laravel-data/v4/advanced-usage/normalizers). + +When a data object cannot be created using magical methods or the default methods, a `CannotCreateData` +exception will be thrown. + +## Optional creation + +It is impossible to return `null` from a data object's `from` method since we always expect a data object when +calling `from`. To solve this, you can call the `optional` method: + +```php +SongData::optional(null); // returns null +``` + +Underneath the optional method will call the `from` method when a value is given, so you can still magically create data +objects. When a null value is given, it will return null. + +## Creation without magic methods + +You can ignore the magical creation methods when creating a data object as such: + +```php +SongData::factory()->withoutMagicalCreation()->from($song); +``` + +## Advanced creation using factories + +It is possible to configure how a data object is created, whether it will be validated, which casts to use and more. You +can read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/factories). + +## DTO classes + +The default `Data` class from which you extend your data objects is a multi versatile class, it packs a lot of +functionality. But sometimes you just want a simple DTO class. You can use the `Dto` class for this: + +```php +class SongData extends Dto +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +The `Dto` class is a data class in its most basic form. It can be created from anything using magical methods, can +validate payloads before creating the data object and can be created using factories. But it doesn't have any of the +other functionality that the `Data` class has. + +]]> + + +date = CarbonImmutable::create(1987, 7, 27); + } +} +``` + +You can now do the following: + +```php +SongData::from(); +SongData::from(['title' => 'Giving Up On Love', 'date' => CarbonImmutable::create(1988, 4, 15)]); +``` + +Even validation will work: + +```php +SongData::validateAndCreate(); +SongData::validateAndCreate(['title' => 'Giving Up On Love', 'date' => CarbonImmutable::create(1988, 4, 15)]); +``` + +There are a few conditions for this approach: + +- You must always use a sole property, a property within the constructor definition won't work +- The optional type is technically not required, but it's a good idea to use it otherwise the validation won't work +- Validation won't be performed on the default value, so make sure it is valid + +]]> + + +from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +Collecting a bunch of data objects using a factory can be done as such: + +```php +SongData::factory()->collect(Song::all()) +``` + +## Disable property name mapping + +We saw [earlier](/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names) that it is possible to map +property names when creating a data object from an array. This can be disabled when using a factory: + +```php +ContractData::factory()->withoutPropertyNameMapping()->from(['name' => 'Rick Astley', 'record_company' => 'RCA Records']); // record_company will not be mapped to recordCompany +``` + +## Changing the validation strategy + +By default, the package will only validate Requests when creating a data object it is possible to change the validation +strategy to always validate for each type: + +```php +SongData::factory()->alwaysValidate()->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +Or completely disable validation: + +```php +SongData::factory()->withoutValidation()->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +## Disabling magic methods + +A data object can be created +using [magic methods](/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object.md#magical-creation) , this can be disabled +when using a factory: + +```php +SongData::factory()->withoutMagicalCreation()->from('Never gonna give you up'); // Won't work since the magical method creation is disabled +``` + +It is also possible to ignore the magical creation methods when creating a data object as such: + +```php +SongData::factory()->ignoreMagicalMethod('fromString')->from('Never gonna give you up'); // Won't work since the magical method is ignored +``` + +## Disabling optional values + +When creating a data object that has optional properties, it is possible choose whether missing properties from the payload should be created as `Optional`. This can be helpful when you want to have a `null` value instead of an `Optional` object - for example, when creating the DTO from an Eloquent model with `null` values. + +```php +class SongData extends Data { + public function __construct( + public string $title, + public string $artist, + public Optional|null|string $album, + ) { + } +} + +SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); // album will `null` instead of `Optional` +``` + +Note that when an Optional property has no default value, and is not nullable, and the payload does not contain a value for this property, the DTO will not have the property set - so accessing it can throw `Typed property must not be accessed before initialization` error. Therefore, it's advisable to either set a default value or make the property nullable, when using `withoutOptionalValues`. + +```php +class SongData extends Data { + public function __construct( + public string $title, + public string $artist, + public Optional|string $album, // careful here! + public Optional|string $publisher = 'unknown', + public Optional|string|null $label, + ) { + } +} + +$data = SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); + +$data->toArray(); // ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley', 'publisher' => 'unknown', 'label' => null] + +$data->album; // accessing the album will throw an error, unless the property is set before accessing it +``` + +## Adding additional global casts + +When creating a data object, it is possible to add additional casts to the data object: + +```php +SongData::factory()->withCast('string', StringToUpperCast::class)->from(['title' => 'Never gonna give you up', 'artist' => 'Rick Astley']); +``` + +These casts will not replace the other global casts defined in the `data.php` config file, they will though run before +the other global casts. You define them just like you would define them in the config file, the first parameter is the +type of the property that should be cast and the second parameter is the cast class. + +## Using the creation context + +Internally the package uses a creation context to create data objects. The factory allows you to use this context manually, but when using the from method it will be used automatically. + +It is possible to inject the creation context into a magical method by adding it as a parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function fromModel(Song $song, CreationContext $context): self + { + // Do something with the context + } +} +``` + +You can read more about creation contexts [here](/docs/laravel-data/v4/advanced-usage/pipeline). + +]]> + +<_index_md> + + + +id`. + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + public string $name; +} +``` + +### Using custom property mapping + +In the example below, `$name` property will be filled with `$song->title` (instead of `$song->name). + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + #[FromRouteParameterProperty('song', 'title')] + public string $name; +} +``` + +### Nested property mapping + +Nested properties are supported as well. Here, we fill `$singerName` from `$artist->leadSinger->name`: + +```php +Route::patch('/artists/{artist}/songs/{song}', [SongController::class, 'update']); + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + #[FromRouteParameterProperty('artist', 'leadSinger.name')] + public string $singerName; +} +``` + +## Route parameters take priority over request body + +By default, route parameters take priority over values in the request body. For example, when the song ID is present in +the route model as well as request body, the ID from route model is used. + +```php +Route::patch('/songs/{song}', [SongController::class, 'update']); + +// PATCH /songs/123 +// { "id": 321, "name": "Never gonna give you up" } + +class SongData extends Data { + #[FromRouteParameterProperty('song')] + public int $id; + public string $name; +} +``` + +Here, `$id` will be `123` even though the request body has `321` as the ID value. + +In most cases, this is useful - especially when you need the ID for a validation rule. However, there may be cases when +the exact opposite is required. + +The above behavior can be turned off by switching the `replaceWhenPresentInPayload` flag off. This can be useful when +you _intend_ to allow updating a property that is present in a route parameter, such as a slug: + +```php +Route::patch('/songs/{slug}', [SongController::class, 'update']); + +// PATCH /songs/never +// { "slug": "never-gonna-give-you-up", "name": "Never gonna give you up" } + +class SongData extends Data { + #[FromRouteParameter('slug', replaceWhenPresentInPayload: false )] + public string $slug; +} +``` + +Here, `$slug` will be `never-gonna-give-you-up` even though the route parameter value is `never`. + +## Filling properties from the authenticated user + +The `FromCurrentUser` attribute allows filling properties with values from the authenticated user. + +```php +class SongData extends Data { + #[FromAuthenticatedUser] + public UserData $user; +} +``` + +It is possible to specify the guard to use when fetching the user: + +```php +class SongData extends Data { + #[FromAuthenticatedUser('api')] + public UserData $user; +} +``` + +Just like with route parameters, it is possible to fill properties with specific user properties using +`FromAuthenticatedUserProperty`: + +```php +class SongData extends Data { + #[FromAuthenticatedUserProperty('api','name')] + public string $username; +} +``` + +All the other features like custom property mapping and not replacing values when present in the payload are supported +as well. + +## Filling properties from the container + +The `FromContainer` attribute allows filling properties with dependencies from the container. + +```php +class SongData extends Data { + #[FromContainer(SongService::class)] + public SongService $song_service; +} +``` + +When a dependency requires additional parameters these can be provided as such: + +```php +class SongData extends Data { + #[FromContainer(SongService::class, parameters: ['year' => 1984])] + public SongService $song_service; +} +``` + +It is even possible to completely inject the container itself: + +```php +class SongData extends Data { + #[FromContainer] + public Container $container; +} +``` + +Selecting a property from a dependency can be done using `FromContainerProperty`: + +```php +class SongData extends Data { + #[FromContainerProperty(SongService::class, 'name')] + public string $service_name; +} +``` + +Again, all the other features like custom property mapping and not replacing values when present in the payload are +supported as well. + +## Creating your own injectable attributes + +All the attributes we saw earlier implement the `InjectsPropertyValue` interface: + +```php +interface InjectsPropertyValue +{ + public function resolve( + DataProperty $dataProperty, + mixed $payload, + array $properties, + CreationContext $creationContext + ): mixed; + + public function shouldBeReplacedWhenPresentInPayload() : bool; +} +``` + +It is possible to create your own attribute by implementing this interface. The `resolve` method is responsible for +returning the value that should be injected into the property. The `shouldBeReplacedWhenPresentInPayload` method should +return `true` if the value should be replaced when present in the payload. + +]]> + + + 'Rick Astley', 'record_company' => 'RCA Records']); +``` + +Changing all property names in a data object to snake_case in the data the object is created from can be done as such: + +```php +#[MapInputName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +You can also use the `MapName` attribute when you want to combine input (see [transforming data objects](/docs/laravel-data/v4/as-a-resource/mapping-property-names)) and output property name mapping: + +```php +#[MapName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +It is possible to set a default name mapping strategy for all data objects in the `data.php` config file: + +```php +'name_mapping_strategy' => [ + 'input' => SnakeCaseMapper::class, + 'output' => null, +], +``` + +## Mapping Nested Properties + +You can also map nested properties using dot notation in the `MapInputName` attribute. This is useful when you want to extract a nested value from an array and assign it to a property in your data object: + +```php +class SongData extends Data +{ + public function __construct( + #[MapInputName("title.name")] + public string $title, + #[MapInputName("artists.0.name")] + public string $artist + ) { + } +} +``` + +You can create the data object from an array with nested structures: + +```php +SongData::from([ + "title" => [ + "name" => "Never gonna give you up" + ], + "artists" => [ + ["name" => "Rick Astley"] + ] +]); +``` + +The package has a set of default mappers available, you can find them [here](/docs/laravel-data/v4/advanced-usage/available-property-mappers). + +]]> + + + 'array' + ]; + } +} +``` + +Within the database the new column will be stored as a JSON string, but in the data object we can just use the array +type: + +```php +class ArtistData extends Data +{ + public int $id; + public string $first_name; + public string $last_name; + public array $properties; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +## Attributes & Accessors + +Laravel allows you to define attributes on a model, these will be called before a data object is created. Let's extend +the model: + +```php +class Artist extends Model +{ + protected function fullName(): Attribute + { + return Attribute::make( + get: fn () => $this->first_name . ' ' . $this->last_name, + ); + } +} +``` + +We now can use the attribute in the data object: + +```php +class ArtistData extends Data +{ + public int $id; + public string $full_name; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +Remember: we need to use the snake_case version of the attribute in the data object since that's how it is stored in the +model. Read on for a more elegant solution when you want to use camelCase property names in your data object. + +It is also possible to define accessors on a model which are the successor of the attributes: + +```php +class Artist extends Model +{ + public function getFullName(): Attribute + { + return Attribute::get(fn () => "{$this->first_name} {$this->last_name}"); + } +} +``` + +With the same data object we created earlier we can now use the accessor. + +## Mapping property names + +Sometimes you want to use camelCase property names in your data object, but the model uses snake_case. You can use +an `MapInputName` to map the property names: + +```php +use Spatie\LaravelData\Attributes\MapInputName; +use Spatie\LaravelData\Mappers\SnakeCaseMapper; + +class ArtistData extends Data +{ + public int $id; + #[MapInputName(SnakeCaseMapper::class)] + public string $fullName; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +An even more elegant solution would be to map every property within the data object: + +```php +#[MapInputName(SnakeCaseMapper::class)] +class ArtistData extends Data +{ + public int $id; + public string $fullName; + public CarbonImmutable $createdAt; + public CarbonImmutable $updatedAt; +} +``` + +## Relations + +Let's create a new model: + +```php +class Song extends Model +{ + public function artist(): BelongsTo + { + return $this->belongsTo(Artist::class); + } +} +``` + +Which has the following columns in the database: + +- id +- artist_id +- title + +We update our previous model as such: + +```php +class Artist extends Model +{ + public function songs(): HasMany + { + return $this->hasMany(Song::class); + } +} +``` + +We can now create a data object like this: + +```php +class SongData extends Data +{ + public int $id; + public string $title; +} +``` + +And update our previous data object like this: + +```php +class ArtistData extends Data +{ + public int $id; + /** @var array */ + public array $songs; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +We can now create a data object with the relations like this: + +```php +$artist = ArtistData::from(Artist::with('songs')->find(1)); +``` + +When you're not loading the relations in advance, `null` will be returned for the relation. + +It is however possible to load the relation on the fly by adding the `LoadRelation` attribute to the property: + +```php +class ArtistData extends Data +{ + public int $id; + /** @var array */ + #[LoadRelation] + public array $songs; + public CarbonImmutable $created_at; + public CarbonImmutable $updated_at; +} +``` + +Now the data object with relations can be created like this: + +```php +$artist = ArtistData::from(Artist::find(1)); +``` + +We even eager-load the relation for performance, neat! + +### Be careful with automatic loading of relations + +Let's update the `SongData` class like this: + +```php +class SongData extends Data +{ + public int $id; + public string $title; + #[LoadRelation] + public ArtistData $artist; +} +``` + +When we now create a data object like this: + +```php +$song = SongData::from(Song::find(1)); +``` + +We'll end up in an infinite loop, since the `SongData` class will try to load the `ArtistData` class, which will try to +load the `SongData` class, and so on. + +## Missing attributes + +When a model is missing attributes and `preventAccessingMissingAttributes` is enabled for a model the `MissingAttributeException` won't be thrown when creating a data object with a property that can be null or Optional. + +]]> + + + 'Never gonna give you up', + 'artist' => [ + 'name' => 'Rick Astley', + 'age' => 22 + ] +]); +``` + +## Collections of data objects + +What if you want to nest a collection of data objects within a data object? + +That's perfectly possible, but there's a small catch; you should always define what kind of data objects will be stored +within the collection. This is really important later on to create validation rules for data objects or partially +transforming data objects. + +There are a few different ways to define what kind of data objects will be stored within a collection. You could use an +annotation, for example, which has an advantage that your IDE will have better suggestions when working with the data +object. And as an extra benefit, static analyzers like PHPStan will also be able to detect errors when your code +is using the wrong types. + +A collection of data objects defined by annotation looks like this: + +```php +/** + * @property \App\Data\SongData[] $songs + */ +class AlbumData extends Data +{ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +or like this when using properties: + +```php +class AlbumData extends Data +{ + public string $title; + + /** @var \App\Data\SongData[] */ + public array $songs; +} +``` + +If you've imported the data class you can use the short notation: + +```php +use App\Data\SongData; + +class AlbumData extends Data +{ + /** @var SongData[] */ + public array $songs; +} +``` + +It is also possible to use generics: + +```php +use App\Data\SongData; + +class AlbumData extends Data +{ + /** @var array */ + public array $songs; +} +``` + +The same is true for Laravel collections, but be sure to use two generic parameters to describe the collection. One for the collection key type and one for the data object type. + +```php +use App\Data\SongData; +use Illuminate\Support\Collection; + +class AlbumData extends Data +{ + /** @var Collection */ + public Collection $songs; +} +``` + +If the collection is well-annotated, the `Data` class doesn't need to use annotations: + +```php +/** + * @template TKey of array-key + * @template TData of \App\Data\SongData + * + * @extends \Illuminate\Support\Collection + */ +class SongDataCollection extends Collection +{ +} + +class AlbumData extends Data +{ + public function __construct( + public string $title, + public SongDataCollection $songs, + ) { + } +} +``` + +You can also use an attribute to define the type of data objects that will be stored within a collection: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public array $songs, + ) { + } +} +``` + +This was the old way to define the type of data objects that will be stored within a collection. It is still supported, but we recommend using the annotation since static analyzers and IDEs will have better support for that. + +```php + +]]> + + + 'Never gonna give you up' +]); +``` + +The value of `artist` will automatically be set to `Optional`. When you transform this data object to an array, it will look like this: + +```php +[ + 'title' => 'Never gonna give you up' +] +``` + +You can manually use `Optional` values within magical creation methods as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string|Optional $artist, + ) { + } + + public static function fromTitle(string $title): static + { + return new self($title, Optional::create()); + } +} +``` + +It is possible to automatically update `Optional` values to `null`: + +```php +class SongData extends Data { + public function __construct( + public string $title, + public Optional|null|string $artist, + ) { + } +} + +SongData::factory() + ->withoutOptionalValues() + ->from(['title' => 'Never gonna give you up']); // artist will `null` instead of `Optional` +``` + +You can read more about this [here](/docs/laravel-data/v4/as-a-data-transfer-object/factories#disabling-optional-values). + +]]> + + +update($data->all()); + + return redirect()->back(); + } +} +``` + +As an added benefit, these values will be validated before the data object is created. If the validation fails, a `ValidationException` will be thrown which will look like you've written the validation rules yourself. + +The package will also automatically validate all requests when passed to the from method: + +```php +class UpdateSongController +{ + public function __invoke( + Song $model, + SongRequest $request + ){ + $model->update(SongData::from($request)->all()); + + return redirect()->back(); + } +} +``` + +We have a complete section within these docs dedicated to validation, you can find it [here](/docs/laravel-data/v4/validation/introduction). + +## Getting the data object filled with request data from anywhere + +You can resolve a data object from the container. + +```php +app(SongData::class); +``` + +We resolve a data object from the container, its properties will already be filled by the values of the request with matching key names. +If the request contains data that is not compatible with the data object, a validation exception will be thrown. + +## Validating a collection of data objects: + +Let's say we want to create a data object like this from a request: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public DataCollection $songs, + ) { + } +} +``` + +Since the `SongData` has its own validation rules, the package will automatically apply them when resolving validation +rules for this object. + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` + +]]> + + + + +additional([ + 'year' => 1987, +]); +``` + +This will output the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'year' => 1987, +] +``` + +When using a closure, you have access to the underlying data object: + +```php +SongData::from(Song::first())->additional([ + 'slug' => fn(SongData $songData) => Str::slug($songData->title), +]); +``` + +Which produces the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'slug' => 'never-gonna-give-you-up', +] +``` + +It is also possible to add extra properties by overwriting the `with` method within your data object: + +```php +class SongData extends Data +{ + public function __construct( + public int $id, + public string $title, + public string $artist + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + $song->id, + $song->title, + $song->artist + ); + } + + public function with() + { + return [ + 'endpoints' => [ + 'show' => action([SongsController::class, 'show'], $this->id), + 'edit' => action([SongsController::class, 'edit'], $this->id), + 'delete' => action([SongsController::class, 'delete'], $this->id), + ] + ]; + } +} +``` + +Now each transformed data object contains an `endpoints` key with all the endpoints for that data object: + +```php +[ + 'id' => 1, + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley', + 'endpoints' => [ + 'show' => 'https://spatie.be/songs/1', + 'edit' => 'https://spatie.be/songs/1', + 'delete' => 'https://spatie.be/songs/1', + ], +] +``` + +]]> + + +toArray(); +``` + +Which will output the following array: + +```php +[ + 'name' => 'Never gonna give you up', + 'artist' => 'Rick Astley' +] +``` + +By default, calling `toArray` on a data object will recursively transform all properties to an array. This means that nested data objects and collections of data objects will also be transformed to arrays. Other complex types like `Carbon`, `DateTime`, `Enums`, etc... will be transformed into a string. We'll see in the [transformers](/docs/laravel-data/v4/as-a-resource/transformers) section how to configure and customize this behavior. + +If you only want to transform a data object to an array without transforming the properties, you can call the `all` method: + +```php +SongData::from(Song::first())->all(); +``` + +You can also manually transform a data object to JSON: + +```php +SongData::from(Song::first())->toJson(); +``` + +## Using collections + +Here's how to create a collection of data objects: + +```php +SongData::collect(Song::all()); +``` + +A collection can be transformed to array: + +```php +SongData::collect(Song::all())->toArray(); +``` + +Which will output the following array: + +```php +[ + [ + "name": "Never Gonna Give You Up", + "artist": "Rick Astley" + ], + [ + "name": "Giving Up on Love", + "artist": "Rick Astley" + ] +] +``` + +## Nesting + +It is possible to nest data objects. + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public string $email, + public SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + $user->email, + SongData::from($user->favorite_song) + ); + } +} +``` + +When transformed to an array, this will look like the following: + +```php +[ + "name": "Ruben", + "email": "ruben@spatie.be", + "favorite_song": [ + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + ] +] +``` + +You can also nest a collection of data objects: + +```php +class AlbumData extends Data +{ + /** + * @param Collection $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + SongData::collect($album->songs) + ); + } +} +``` + +As always, remember to type collections of data objects by annotation or the `DataCollectionOf` attribute, this is essential to transform these collections correctly. + +]]> + + + 'Title of the song here', + 'artist' => 'An artist' +]); +``` + +Or filter the properties that should be included in the empty response: + +```php +SongData::empty(only: ['name']); // Will only return the `name` property + +SongData::empty(except: ['name']); // Will return the `artist` property +``` + +## Response status code + +When a resource is being returned from a controller, the status code of the response will automatically be set to `201 CREATED` when Laravel data detects that the request's method is `POST`. In all other cases, `200 OK` will be returned. + +## Resource classes + +To make it a bit more clear that a data object is a resource, you can use the `Resource` class instead of the `Data` class: + +```php +use Spatie\LaravelData\Resource; + +class SongResource extends Resource +{ + public function __construct( + public string $title, + public string $artist, + ) { + } +} +``` + +These resource classes have as an advantage that they won't validate data or check authorization, They are only used to transform data which makes them a bit faster. + +]]> + +<_index_md> + + + + $songs + */ + public function __construct( + public string $title, + public Collection $songs, + ) { + } +} +``` + +This will always output a collection of songs, which can become quite large. With lazy properties, we can include +properties when we want to: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + Lazy::create(fn() => SongData::collect($album->songs)) + ); + } +} +``` + +The `songs` key won't be included in the resource when transforming it from a model. Because the closure that provides +the data won't be called when transforming the data object unless we explicitly demand it. + +Now when we transform the data object as such: + +```php +AlbumData::from(Album::first())->toArray(); +``` + +We get the following array: + +```php +[ + 'title' => 'Together Forever', +] +``` + +As you can see, the `songs` property is missing in the array output. Here's how you can include it. + +```php +AlbumData::from(Album::first())->include('songs'); +``` + +## Including lazy properties + +Lazy properties will only be included when the `include` method is called on the data object with the property's name. + +It is also possible to nest these includes. For example, let's update the `SongData` class and make all of its +properties lazy: + +```php +class SongData extends Data +{ + public function __construct( + public Lazy|string $title, + public Lazy|string $artist, + ) { + } + + public static function fromModel(Song $song): self + { + return new self( + Lazy::create(fn() => $song->title), + Lazy::create(fn() => $song->artist) + ); + } +} +``` + +Now `name` or `artist` should be explicitly included. This can be done as such on the `AlbumData`: + +```php +AlbumData::from(Album::first())->include('songs.name', 'songs.artist'); +``` + +Or you could combine these includes: + +```php +AlbumData::from(Album::first())->include('songs.{name, artist}'); +``` + +If you want to include all the properties of a data object, you can do the following: + +```php +AlbumData::from(Album::first())->include('songs.*'); +``` + +Explicitly including properties of data objects also works on a single data object. For example, our `UserData` looks +like this: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + Lazy::create(fn() => SongData::from($user->favorite_song)) + ); + } +} +``` + +We can include properties of the data object just like we would with collections of data objects: + +```php +return UserData::from(Auth::user())->include('favorite_song.name'); +``` + +## Types of Lazy properties + +### Conditional Lazy properties + +You can include lazy properties in different ways: + +```php +Lazy::create(fn() => SongData::collect($album->songs)); +``` + +With a basic `Lazy` property, you must explicitly include it when the data object is transformed. + +Sometimes you only want to include a property when a specific condition is true. This can be done with conditional lazy +properties: + +```php +Lazy::when(fn() => $this->is_admin, fn() => SongData::collect($album->songs)); +``` + +The property will only be included when the `is_admin` property of the data object is true. It is not possible to +include the property later on with the `include` method when a condition is not accepted. + +### Relational Lazy properties + +You can also only include a lazy property when a particular relation is loaded on the model as such: + +```php +Lazy::whenLoaded('songs', $album, fn() => SongData::collect($album->songs)); +``` + +Now the property will only be included when the song's relation is loaded on the model. + +## Default included lazy properties + +It is possible to mark a lazy property as included by default: + +```php +Lazy::create(fn() => SongData::collect($album->songs))->defaultIncluded(); +``` + +The property will now always be included when the data object is transformed. You can explicitly exclude properties that +were default included as such: + +```php +AlbumData::create(Album::first())->exclude('songs'); +``` + +## Auto Lazy + +Writing Lazy properties can be a bit cumbersome. It is often a repetitive task to write the same code over and over +again while the package can infer almost everything. + +Let's take a look at our previous example: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + Lazy::create(fn() => SongData::from($user->favorite_song)) + ); + } +} +``` + +The package knows how to get the property from the model and wrap it into a data object, but since we're using a lazy +property, we need to write our own magic creation method with a lot of repetitive code. + +In such a situation auto lazy might be a good fit, instead of casting the property directly into the data object, the +casting process is wrapped in a lazy Closure. + +This makes it possible to rewrite the example as such: + +```php +#[AutoLazy] +class UserData extends Data +{ + public function __construct( + public string $title, + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +While achieving the same result! + +Auto Lazy wraps the casting process of a value for every property typed as `Lazy` into a Lazy Closure when the +`AutoLazy` attribute is present on the class. + +It is also possible to use the `AutoLazy` attribute on a property level: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoLazy] + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +The auto lazy process won't be applied in the following situations: + +- When a null value is passed to the property +- When the property value isn't present in the input payload and the property typed as `Optional` +- When a Lazy Closure is passed to the property + +### Auto lazy with model relations + +When you're constructing a data object from an Eloquent model, it is also possible to automatically create lazy +properties for model relations which are only resolved when the relation is loaded: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy] + public Lazy|SongData $favoriteSong, + ) { + } +} +``` + +When the `favoriteSong` relation is loaded on the model, the property will be included in the data object. + +If the name of the relation doesn't match the property name, you can specify the relation name: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy('favoriteSong')] + public Lazy|SongData $favorite_song, + ) { + } +} +``` + +The package will use the regular casting process when the relation is loaded, so it is also perfectly possible to create a collection of data objects: + +```php +class UserData extends Data +{ + /** + * @param Lazy|array $favoriteSongs + */ + public function __construct( + public string $title, + #[AutoWhenLoadedLazy] + public Lazy|array $favoriteSongs, + ) { + } +} +``` + +## Only and Except + +Lazy properties are great for reducing payloads sent over the wire. However, when you completely want to remove a +property Laravel's `only` and `except` methods can be used: + +```php +AlbumData::from(Album::first())->only('songs'); // will only show `songs` +AlbumData::from(Album::first())->except('songs'); // will show everything except `songs` +``` + +It is also possible to use multiple keys: + +```php +AlbumData::from(Album::first())->only('songs.name', 'songs.artist'); +AlbumData::from(Album::first())->except('songs.name', 'songs.artist'); +``` + +And special keys like described above: + +```php +AlbumData::from(Album::first())->only('songs.{name, artist}'); +AlbumData::from(Album::first())->except('songs.{name, artist}'); +``` + +Only and except always take precedence over include and exclude, which means that when a property is hidden by `only` or +`except` it is impossible to show it again using `include`. + +### Conditionally + +It is possible to add an `include`, `exclude`, `only` or `except` if a certain condition is met: + +```php +AlbumData::from(Album::first())->includeWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->excludeWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->onlyWhen('songs', auth()->user()->isAdmin); +AlbumData::from(Album::first())->except('songs', auth()->user()->isAdmin); +``` + +You can also use the values of the data object in such condition: + +```php +AlbumData::from(Album::first())->includeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->excludeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->onlyWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +AlbumData::from(Album::first())->exceptWhen('songs', fn(AlbumData $data) => count($data->songs) > 0); +``` + +In some cases, you may want to define an include on a class level by implementing a method: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs' => $this->title === 'Together Forever', + ]; + } +} +``` + +It is even possible to include nested properties: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs.title' => $this->title === 'Together Forever', + ]; + } +} +``` + +You can define exclude, except and only partials on a data class: + +- You can define **excludes** in a `excludeProperties` method +- You can define **except** in a `exceptProperties` method +- You can define **only** in a `onlyProperties` method + +## Using query strings + +It is possible to include or exclude lazy properties by the URL query string: + +For example, when we create a route `my-account`: + +```php +// in web.php + +Route::get('my-account', fn() => UserData::from(User::first())); +``` + +We now specify that a key of the data object is allowed to be included by query string on the data object: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return ['favorite_song']; + } + + // ... +} +``` + +Our JSON would look like this when we request `https://spatie.be/my-account`: + +```json +{ + "name" : "Ruben Van Assche" +} +``` + +We can include `favorite_song` by adding it to the query in the URL as such: + +``` +https://spatie.be/my-account?include=favorite_song +``` + +```json +{ + "name" : "Ruben Van Assche", + "favorite_song" : { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + } +} +``` + +We can also include multiple properties by separating them with a comma: + +``` +https://spatie.be/my-account?include=favorite_song,favorite_movie +``` + +Or by using a group input: + +``` +https://spatie.be/my-account?include[]=favorite_song&include[]=favorite_movie +``` + +Including properties works for data objects and data collections. + +### Allowing includes by query string + +By default, it is disallowed to include properties by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return []; + } +} +``` + +You can pass several names of properties which are allowed to be included by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return ['favorite_song', 'name']; + } +} +``` + +Or you can allow all properties to be included by query string: + +```php +class UserData extends Data +{ + public static function allowedRequestIncludes(): ?array + { + return null; + } +} +``` + +### Other operations + +It is also possible to run exclude, except and only operations on a data object: + +- You can define **excludes** in `allowedRequestExcludes` and use the `exclude` key in your query string +- You can define **except** in `allowedRequestExcept` and use the `except` key in your query string +- You can define **only** in `allowedRequestOnly` and use the `only` key in your query string + +## Mutability + +Adding includes/excludes/only/except to a data object will only affect the data object (and its nested chain) once: + +```php +AlbumData::from(Album::first())->include('songs')->toArray(); // will include songs +AlbumData::from(Album::first())->toArray(); // will not include songs +``` + +If you want to add includes/excludes/only/except to a data object and its nested chain that will be used for all future +transformations, you can define them in their respective *properties methods: + +```php +class AlbumData extends Data +{ + /** + * @param Lazy|Collection $songs + */ + public function __construct( + public string $title, + public Lazy|Collection $songs, + ) { + } + + public function includeProperties(): array + { + return [ + 'songs' + ]; + } +} +``` + +Or use the permanent methods: + +```php +AlbumData::from(Album::first())->includePermanently('songs'); +AlbumData::from(Album::first())->excludePermanently('songs'); +AlbumData::from(Album::first())->onlyPermanently('songs'); +AlbumData::from(Album::first())->exceptPermanently('songs'); +``` + +When using a conditional includes/excludes/only/except, you can set the permanent flag: + +```php +AlbumData::from(Album::first())->includeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +AlbumData::from(Album::first())->excludeWhen('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +AlbumData::from(Album::first())->onlyWhen('songs', fn(AlbumData $data) => count($data->songs) > 0), permanent: true); +AlbumData::from(Album::first())->except('songs', fn(AlbumData $data) => count($data->songs) > 0, permanent: true); +``` + +]]> + + + 'Rick Astley', + 'record_company' => 'RCA Records', +] +``` + +Changing all property names in a data object to snake_case as output data can be done as such: + +```php +#[MapOutputName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +You can also use the `MapName` attribute when you want to combine input and output property name mapping: + +```php +#[MapName(SnakeCaseMapper::class)] +class ContractData extends Data +{ + public function __construct( + public string $name, + public string $recordCompany, + ) { + } +} +``` + +It is possible to set a default name mapping strategy for all data objects in the `data.php` config file: + +```php +'name_mapping_strategy' => [ + 'input' => null, + 'output' => SnakeCaseMapper::class, +], +``` + +You can now create a data object as such: + +```php +$contract = new ContractData( + name: 'Rick Astley', + recordCompany: 'RCA Records', +); +``` + +And a transformed version of the data object will look like this: + +```php +[ + 'name' => 'Rick Astley', + 'record_company' => 'RCA Records', +] +``` + +The package has a set of default mappers available, you can find them [here](/docs/laravel-data/v4/advanced-usage/available-property-mappers). + +]]> + + + [ + DateTimeInterface::class => DateTimeInterfaceTransformer::class, + Arrayable::class => ArrayableTransformer::class, +], +``` + +The package will look through these global transformers and tries to find a suitable transformer. You can define transformers for: + +- a **specific implementation** (e.g. CarbonImmutable) +- an **interface** (e.g. DateTimeInterface) +- a **base class** (e.g. Enum) + +## Getting a data object without transforming + +It is possible to get an array representation of a data object without transforming the properties. This means `Carbon` objects won't be transformed into strings. And also, nested data objects and `DataCollection`s won't be transformed into arrays. You can do this by calling the `all` method on a data object like this: + +```php +ArtistData::from($artist)->all(); +``` + +## Getting a data object (on steroids) + +Internally the package uses the `transform` method for operations like `toArray`, `all`, `toJson` and so on. This method is highly configurable, when calling it without any arguments it will behave like the `toArray` method: + +```php +ArtistData::from($artist)->transform(); +``` + +Producing the following result: + +```php +[ + 'name' => 'Rick Astley', + 'birth_date' => '06-02-1966', +] +``` + +It is possible to disable the transformation of values, which will make the `transform` method behave like the `all` method: + +```php +use Spatie\LaravelData\Support\Transformation\TransformationContext; + +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withoutValueTransformation() +); +``` + +Outputting the following array: + +```php +[ + 'name' => 'Rick Astley', + 'birth_date' => Carbon::parse('06-02-1966'), +] +``` + +The [mapping of property names](/docs/laravel-data/v4/as-a-resource/mapping-property-names) can also be disabled: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withoutPropertyNameMapping() +); +``` + +It is possible to enable [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping-data) the data object: + +```php +use Spatie\LaravelData\Support\Wrapping\WrapExecutionType; + +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withWrapping() +); +``` + +Outputting the following array: + +```php +[ + 'data' => [ + 'name' => 'Rick Astley', + 'birth_date' => '06-02-1966', + ], +] +``` + +You can also add additional global transformers as such: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->withGlobalTransformer( + 'string', + StringToUpperTransformer::class + ) +); +``` + +## Transformation depth + +When transforming a complicated structure of nested data objects it is possible that an infinite loop is created of data objects including each other. +To prevent this, a transformation depth can be set, when that depth is reached when transforming, either an exception will be thrown or an empty +array is returned, stopping the transformation. + +This transformation depth can be set globally in the `data.php` config file: + +```php +'max_transformation_depth' => 20, +``` + +Setting the transformation depth to `null` will disable the transformation depth check: + +```php +'max_transformation_depth' => null, +``` + +It is also possible if a `MaxTransformationDepthReached` exception should be thrown or an empty array should be returned: + +```php +'throw_when_max_transformation_depth_reached' => true, +``` + +It is also possible to set the transformation depth on a specific transformation by using a `TransformationContextFactory`: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->maxDepth(20) +); +``` + +By default, an exception will be thrown when the maximum transformation depth is reached. This can be changed to return an empty array as such: + +```php +ArtistData::from($artist)->transform( + TransformationContextFactory::create()->maxDepth(20, throw: false) +); +``` + +]]> + + +wrap('data'); +``` + +Now the JSON looks like this: + +```json +{ + "data" : { + "name" : "Never gonna give you up", + "artist" : "Rick Astley" + } +} +``` + +Data objects and collections will only get wrapped when you're sending them as a response and never when calling `toArray` or `toJson` on it. + +It is possible to define a default wrap key inside a data object: + +```php +class SongData extends Data +{ + public function defaultWrap(): string + { + return 'data'; + } + + // ... +} +``` + +Or you can set a global wrap key inside the `data.php` config file: + +```php + /* + * Data objects can be wrapped into a key like 'data' when used as a resource, + * this key can be set globally here for all data objects. You can pass in + * `null` if you want to disable wrapping. + */ + 'wrap' => 'data', +``` + +## Wrapping collections + +Collections can be wrapped just like data objects: + +```php +SongData::collect(Song::all(), DataCollection::class)->wrap('data'); +``` + +Notice here, for now we only support wrapping `DataCollections`, `PaginatedDataCollections` and `CursorPaginatedDataCollections` on the root level. Wrapping won't work for Laravel Collections or arrays (for now) since the package cannot interfere. Nested properties with such types can be wrapped though (see further). + +The JSON will now look like this: + +```json +{ + "data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ] +} +``` + +It is possible to set the data key in paginated collections: + +```php +SongData::collect(Song::paginate(), PaginatedDataCollection::class)->wrap('paginated_data'); +``` + +Which will let the JSON look like this: + +```json +{ + "paginated_data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ], + "meta" : { + "current_page" : 1, + "first_page_url" : "https://spatie.be/?page=1", + "from" : 1, + "last_page" : 7, + "last_page_url" : "https://spatie.be/?page=7", + "next_page_url" : "https://spatie.be/?page=2", + "path" : "https://spatie.be/", + "per_page" : 15, + "prev_page_url" : null, + "to" : 15, + "total" : 100 + } +} +``` + +## Nested wrapping + +A data object included inside another data object will never be wrapped even if a wrap is set: + +```php +class UserData extends Data +{ + public function __construct( + public string $title, + public string $email, + public SongData $favorite_song, + ) { + } + + public static function fromModel(User $user): self + { + return new self( + $user->title, + $user->email, + SongData::create($user->favorite_song)->wrap('data') + ); + } +} + +UserData::from(User::first())->wrap('data'); +``` + +```json +{ + "data" : { + "name" : "Ruben", + "email" : "ruben@spatie.be", + "favorite_song" : { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + } + } +} +``` + +A data collection inside a data object will get wrapped when a wrapping key is set (in order to mimic Laravel resources): + +```php +use Spatie\LaravelData\Attributes\DataCollectionOf; +use Spatie\LaravelData\DataCollection; + +class AlbumData extends Data +{ + public function __construct( + public string $title, + #[DataCollectionOf(SongData::class)] + public DataCollection $songs, + ) { + } + + public static function fromModel(Album $album): self + { + return new self( + $album->title, + SongData::collect($album->songs, DataCollection::class)->wrap('data') + ); + } +} + +AlbumData::from(Album::first())->wrap('data'); +``` + +The JSON will look like this: + +```json +{ + "data" : { + "title" : "Whenever You Need Somebody", + "songs": { + "data" : [ + { + "name" : "Never Gonna Give You Up", + "artist" : "Rick Astley" + }, + { + "name" : "Giving Up on Love", + "artist" : "Rick Astley" + } + ] + } + } +} +``` + +## Disabling wrapping + +Whenever a data object is wrapped due to the default wrap method or a global wrap key, it is possible to disable wrapping on a data object/collection: + +```php +SongData::from(Song::first())->withoutWrapping(); +``` + +## Getting a wrapped array + +By default, `toArray` and `toJson` will never wrap a data object or collection, but it is possible to get a wrapped array: + +```php +SongData::from(Song::first())->wrap('data')->transform(wrapExecutionType: WrapExecutionType::Enabled); +``` + +]]> + + + + + + +<_index_md> + + + + 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'published_at' => CarbonImmutable::now(), +]); +``` + +Or a `Post` model with the required properties: + +```php +class Post extends Model +{ + protected $guarded = []; + + protected $casts = [ + 'status' => PostStatus::class, + 'published_at' => 'immutable_datetime', + ]; +} +``` + +Can be quickly transformed into a `PostData` object: + +```php +PostData::from(Post::findOrFail($id)); +``` + +## Using requests + +Let's say we have a Laravel request coming from the frontend with these properties. Our controller would then validate these properties, and then it would store them in a model; this can be done as such: + +```php +class DataController +{ + public function __invoke(Request $request) + { + $request->validate($this->rules()); + + $postData = PostData::from([ + 'title' => $request->input('title'), + 'content' => $request->input('content'), + 'status' => $request->enum('status', PostStatus::class), + 'published_at' => $request->has('published_at') + ? CarbonImmutable::createFromFormat(DATE_ATOM, $request->input('published_at')) + : null, + ]); + + Post::create($postData->toArray()); + + return redirect()->back(); + } + + private function rules(): array + { + return [ + 'title' => ['required', 'string'], + 'content' => ['required', 'string'], + 'status' => ['required', new Enum(PostStatus::class)], + 'published_at' => ['nullable', 'date'], + ]; + } +} +``` + +That's a lot of code to fill a data object, using laravel data we can remove a lot of code: + +```php +class DataController +{ + public function __invoke(PostData $postData) + { + Post::create($postData->toArray()); + + return redirect()->back(); + } +} +``` + +Let's see what's happening: + +1) Laravel boots up, and the router directs to the `DataController` +2) Because we're injecting `PostData`, two things happen + - `PostData` will generate validation rules based on the property types and validate the request + - The `PostData` object is automatically created from the request +3) We're now in the `__invoke` method with a valid `PostData` object + +You can always check the generated validation rules of a data object like this: + +```php +class DataController +{ + public function __invoke(Request $request) + { + dd(PostData::getValidationRules($request->toArray())); + } +} +``` + +Which provides us with the following set of rules: + +```php +array:4 [ + "title" => array:2 [ + 0 => "required" + 1 => "string" + ] + "content" => array:2 [ + 0 => "required" + 1 => "string" + ] + "status" => array:2 [ + 0 => "required" + 1 => Illuminate\Validation\Rules\Enum { + #type: "App\Enums\PostStatus" + } + ] + "published_at" => array:1 [ + 0 => "nullable" + ] +] +``` + +As you can see, we're missing the `date` rule on the `published_at` property. By default, this package will automatically generate the following rules: + +- `required` when a property cannot be `null` +- `nullable` when a property can be `null` +- `numeric` when a property type is `int` +- `string` when a property type is `string` +- `boolean` when a property type is `bool` +- `numeric` when a property type is `float` +- `array` when a property type is `array` +- `enum:*` when a property type is a native enum + +You can read more about the process of automated rule generation [here](/docs/laravel-data/v4/as-a-data-transfer-object/request-to-data-object#content-automatically-inferring-rules-for-properties-1). + +We can easily add the date rule by using an attribute to our data object: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +Now our validation rules look like this: + +```php +array:4 [ + "title" => array:2 [ + 0 => "required" + 1 => "string" + ] + "content" => array:2 [ + 0 => "required" + 1 => "string" + ] + "status" => array:2 [ + 0 => "required" + 1 => Illuminate\Validation\Rules\Enum { + #type: "App\Enums\PostStatus" + } + ] + "published_at" => array:2 [ + 0 => "nullable" + 1 => "date" + ] +] +``` + +There are [tons](/docs/laravel-data/v4/advanced-usage/validation-attributes) of validation rule attributes you can add to data properties. There's still much more you can do with validating data objects. Read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/request-to-data-object#validating-a-request). + +Tip: By default, when creating a data object in a non request context, no validation is executed: + +```php +$post = PostData::from([ + // As long as PHP accepts the values for the properties, the object will be created +]); +``` + +You can create validated objects without requests like this: + +```php +$post = PostData::validateAndCreate([ + // Before creating the object, each value will be validated +]); +``` + +## Casting data + +Let's send the following payload to the controller: + +```json +{ + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "published_at" : "2021-09-24T13:31:20+00:00" +} +``` + +We get the `PostData` object populated with the values in the JSON payload, neat! But how did the package convert the `published_at` string into a `CarbonImmutable` object? + +It is possible to define casts within the `data.php` config file. By default, the casts list looks like this: + +```php +'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, +], +``` + +This code means that if a class property is of type `DateTime`, `Carbon`, `CarbonImmutable`, ... it will be automatically cast. + +You can create your own casts; read more about it [here](/docs/laravel-data/v4/advanced-usage/creating-a-cast). + +### Local casts + +Sometimes you need one specific cast in one specific data object; in such a case defining a local cast specific for the data object is a good option. + +Let's say we have an `Image` class: + +```php +class Image +{ + public function __construct( + public string $file, + public int $size, + ) { + } +} +``` + +There are two options how an `Image` can be created: + +a) From a file upload +b) From an array when the image has been stored in the database + +Let's create a cast for this: + +```php +use Illuminate\Http\UploadedFile; +use Spatie\LaravelData\Casts\Cast; +use Spatie\LaravelData\Casts\Uncastable; +use Spatie\LaravelData\Support\DataProperty; +use Str; + +class ImageCast implements Cast +{ + public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): Image|Uncastable + { + // Scenario A + if ($value instanceof UploadedFile) { + $filename = $value->store('images', 'public'); + + return new Image( + $filename, + $value->getSize(), + ); + } + + // Scenario B + if (is_array($value)) { + return new Image( + $value['filename'], + $value['size'], + ); + } + + return Uncastable::create(); + } +} + +``` + +Ultimately, we return `Uncastable`, telling the package to try other casts (if available) because this cast cannot cast the value. + +The last thing we need to do is add the cast to our property. We use the `WithCast` attribute for this: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +You can read more about casting [here](/docs/laravel-data/v4/as-a-data-transfer-object/casts). + +## Customizing the creation of a data object + +We've seen the powerful `from` method on data objects, you can throw anything at it, and it will cast the value into a data object. But what if it can't cast a specific type, or what if you want to change how a type is precisely cast into a data object? + +It is possible to manually define how a type is converted into a data object. What if we would like to support to create posts via an email syntax like this: + +``` +title|status|content +``` + +Creating a `PostData` object would then look like this: + +```php +PostData::from('Hello laravel-data|draft|This is an introduction post for the new package'); +``` + +To make this work, we need to add a magic creation function within our data class: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } + + public static function fromString(string $post): PostData + { + $fields = explode('|', $post); + + return new self( + $fields[0], + $fields[2], + PostStatus::from($fields[1]), + null, + null + ); + } +} +``` + +Magic creation methods allow you to create data objects from any type by passing them to the `from` method of a data +object, you can read more about it [here](/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object#content-magical-creation). + +It can be convenient to transform more complex models than our `Post` into data objects because you can decide how a model +would be mapped onto a data object. + +## Nesting data objects and arrays of data objects + +Now that we have a fully functional post-data object. We're going to create a new data object, `AuthorData`, that will store the name of an author and an array of posts the author wrote: + +```php +use Spatie\LaravelData\Attributes\DataCollectionOf; + +class AuthorData extends Data +{ + /** + * @param array $posts + */ + public function __construct( + public string $name, + public array $posts + ) { + } +} +``` + +Notice that we've typed the `$posts` property as an array of `PostData` objects using a docblock. This will be very useful later on! The package always needs to know what type of data objects are stored in an array. Of course, when you're storing other types then data objects this is not required but recommended. + +We can now create an author object as such: + +```php +new AuthorData( + 'Ruben Van Assche', + PostData::collect([ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::draft, + ], + [ + 'title' => 'What is a data object', + 'content' => 'How does it work', + 'status' => PostStatus::published, + ], + ]) +); +``` + +As you can see, the `collect` method can create an array of the `PostData` objects. + +But there's another way; thankfully, our `from` method makes this process even more straightforward: + +```php +AuthorData::from([ + 'name' => 'Ruben Van Assche', + 'posts' => [ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::draft, + ], + [ + 'title' => 'What is a data object', + 'content' => 'How does it work', + 'status' => PostStatus::published, + ], + ], +]); +``` + +The data object is smart enough to convert an array of posts into an array of post data. Mapping data coming from the front end was never that easy! + +### Nesting objects + +Nesting an individual data object into another data object is perfectly possible. Remember the `Image` class we created? We needed a cast for it, but it is a perfect fit for a data object; let's create it: + +```php +class ImageData extends Data +{ + public function __construct( + public string $filename, + public string $size, + ) { + } + + public static function fromUploadedImage(UploadedFile $file): self + { + $stored = $file->store('images', 'public'); + + return new ImageData( + url($stored), + $file->getSize(), + ); + } +} +``` + +In our `ImageCast`, the image could be created from a file upload or an array; we'll handle that first case with the `fromUploadedImage` magic method. Because `Image` is now `ImageData,` the second case is automatically handled by the package, neat! + +We'll update our `PostData` object as such: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +Creating a `PostData` object now can be done as such: + +```php +return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'image' => [ + 'filename' => 'images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png', + 'size' => 16524 + ], + 'published_at' => CarbonImmutable::create(2020, 05, 16), +]); +``` + +When we create the `PostData` object in a controller as such: + +```php +public function __invoke(PostData $postData) +{ + return $postData; +} +``` + +We get a validation error: + +```json +{ + "message": "The image must be an array. (and 2 more errors)", + "errors": { + "image": [ + "The image must be an array." + ], + "image.filename": [ + "The image.filename field is required." + ], + "image.size": [ + "The image.size field is required." + ] + } +} +``` + +This is a neat feature of data; it expects a nested `ImageData` data object when being created from the request, an array with the keys `filename` and `size`. + +We can completely skip validation for the `image` property by using the `WithoutValidation` attribute: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithoutValidation] + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +It is possible to override the validation rules generated by the package by defining a static `rules` method on the data object: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + public ?ImageData $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'status' => ['nullable', 'in:published'], + ]; + } +} +``` + +Please notice that it is impossible to override rules for nested data objects; those are always generated based on the nested data object's properties. + +## Usage in controllers + +We've been creating many data objects from all sorts of values, time to change course and go the other way around and start transforming data objects into arrays. + +Let's say we have an API controller that returns a post: + +```php +public function __invoke() +{ + return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'published_at' => CarbonImmutable::create(2020, 05, 16), + ]); +} +``` + +By returning a data object in a controller, it is automatically converted to JSON: + +```json +{ + "title": "Hello laravel-data", + "content": "This is an introduction post for the new package", + "status": "published", + "image": null, + "published_at": "2020-05-16T00:00:00+00:00" +} +``` + +You can also easily convert a data object into an array as such: + +```php +$postData->toArray(); +``` + +Which gives you an array like this: + +```php +array:5 [ + "title" => "Hello laravel-data" + "content" => "This is an introduction post for the new package" + "status" => "published" + "image" => null + "published_at" => "2020-05-16T00:00:00+00:00" +] +``` + +It is possible to transform a data object into an array and keep complex types like the `PostStatus` and `CarbonImmutable`: + +```php +$postData->all(); +``` + +This will give the following array: + +```php +array:5 [ + "title" => "Hello laravel-data" + "content" => "This is an introduction post for the new package" + "status" => App\Enums\PostStatus { + +name: "published" + +value: "published" + } + "image" => null + "published_at" => Carbon\CarbonImmutable { + ... + } +] + +``` + +As you can see, if we transform a data object to JSON, the `CarbonImmutable` published at date is transformed into a string. + +## Using transformers + +A few sections ago, we used casts to cast simple types into complex types. Transformers work the other way around. They transform complex types into simple ones and transform a data object into a simpler structure like an array or JSON. + +Like the `DateTimeInterfaceCast`, we also have a `DateTimeInterfaceTransformer` that converts `DateTime,` `Carbon,`... objects into strings. + +This `DateTimeInterfaceTransformer` is registered in the `data.php` config file and will automatically be used when a data object needs to transform a `DateTimeInterface` object: + +```php +'transformers' => [ + DateTimeInterface::class => \Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer::class, + \Illuminate\Contracts\Support\Arrayable::class => \Spatie\LaravelData\Transformers\ArrayableTransformer::class, +], +``` + +Remember the image object we created earlier; we stored a file size and filename in the object. But that could be more useful; let's provide the URL to the file when transforming the object. Just like casts, transformers also can be local. Let's implement one for `Image`: + +```php +class ImageTransformer implements Transformer +{ + public function transform(DataProperty $property, mixed $value, TransformationContext $context): string + { + if (! $value instanceof Image) { + throw new Exception("Not an image"); + } + + return url($value->filename); + } +} +``` + +We can now use this transformer in the data object like this: + +```php +class PostData extends Data +{ + public function __construct( + public string $title, + public string $content, + public PostStatus $status, + #[WithCast(ImageCast::class)] + #[WithTransformer(ImageTransformer::class)] + public ?Image $image, + #[Date] + public ?CarbonImmutable $published_at + ) { + } +} +``` + +In our controller, we return the object as such: + +```php +public function __invoke() +{ + return PostData::from([ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => PostStatus::published, + 'image' => [ + 'filename' => 'images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png', + 'size' => 16524 + ], + 'published_at' => CarbonImmutable::create(2020, 05, 16), + ]); +} +``` + +Which leads to the following JSON: + +```php +{ + "title": "Hello laravel-data", + "content": "This is an introduction post for the new package", + "status": "published", + "image": "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png", + "published_at": "2020-05-16T00:00:00+00:00" +} +``` + +You can read more about transformers [here](/docs/laravel-data/v4/as-a-resource/transformers). + +## Generating a blueprint + +We can now send our posts as JSON to the front, but what if we want to create a new post? When using Inertia, for example, we might need an empty blueprint object like this that the user could fill in: + +```json +{ + "title" : null, + "content" : null, + "status" : null, + "image": null, + "published_at" : null +} +``` + +Such an array can be generated with the `empty` method, which will return an empty array following the structure of your data object: + +```php +PostData::empty(); +``` + +Which will return the following array: + +```php +[ + 'title' => null, + 'content' => null, + 'status' => null, + 'image' => null, + 'published_at' => null, +] +``` + +It is possible to set the status of the post to draft by default: + +```php +PostData::empty([ + 'status' => PostStatus::draft; +]); +``` + +## Lazy properties + +For the last section of this quickstart, we will look at the `AuthorData` object again; let's say that we want to compose a list of all the authors. What if we had 100+ authors who have all written more than 100+ posts: + +```json +[ + { + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "image" : "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png", + "published_at" : "2021-09-24T13:31:20+00:00" + } + + // ... + ] + }, + { + "name" : "Freek van der Herten", + "posts" : [ + { + "title" : "Hello laravel-event-sourcing", + "content" : "This is an introduction post for the new package", + "status" : "published", + "image" : "http://laravel-playbox.test/images/8JQtgd0XaPtt9CqkPJ3eWFVV4BAp6JR9ltYAIKqX.png" + "published_at" : "2021-09-24T13:31:20+00:00" + } + + // ... + ] + } + + // ... +] +``` + +As you can see, this will quickly be a large set of data we would send over JSON, which we don't want to do. Since each author includes his name and all the posts, he has written. + +In the end, we only want something like this: + +```json +[ + { + "name" : "Ruben Van Assche" + }, + { + "name" : "Freek van der Herten" + } + + // ... +] +``` + +This functionality can be achieved with lazy properties. Lazy properties are only added to a payload when we explicitly ask it. They work with closures that are executed only when this is required: + +```php +class AuthorData extends Data +{ + /** + * @param Collection|Lazy $posts + */ + public function __construct( + public string $name, + public Collection|Lazy $posts + ) { + } + + public static function fromModel(Author $author) + { + return new self( + $author->name, + Lazy::create(fn() => PostData::collect($author->posts)) + ); + } +} +``` + +When we now create a new author: + +```php +$author = Author::create([ + 'name' => 'Ruben Van Assche' +]); + +$author->posts()->create([ + [ + 'title' => 'Hello laravel-data', + 'content' => 'This is an introduction post for the new package', + 'status' => 'draft', + 'published_at' => null, + ] +]); + +AuthorData::from($author); +``` + +Transforming it into JSON looks like this: + +```json +{ + "name" : "Ruben Van Assche" +} +``` + +If we want to include the posts, the only thing we need to do is this: + +```php +$postData->include('posts')->toJson(); +``` + +Which will result in this JSON: + +```json +{ + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data", + "content" : "This is an introduction post for the new package", + "status" : "published", + "published_at" : "2021-09-24T13:31:20+00:00" + } + ] +} +``` + +Let's take this one step further. What if we want to only include the title of each post? We can do this by making all the other properties within the post data object also lazy: + +```php +class PostData extends Data +{ + public function __construct( + public string|Lazy $title, + public string|Lazy $content, + public PostStatus|Lazy $status, + #[WithoutValidation] + #[WithCast(ImageCast::class)] + #[WithTransformer(ImageTransformer::class)] + public ImageData|Lazy|null $image, + #[Date] + public CarbonImmutable|Lazy|null $published_at + ) { + } + + public static function fromModel(Post $post): PostData + { + return new self( + Lazy::create(fn() => $post->title), + Lazy::create(fn() => $post->content), + Lazy::create(fn() => $post->status), + Lazy::create(fn() => $post->image), + Lazy::create(fn() => $post->published_at) + ); + } + + public static function rules(ValidationContext $context): array + { + return [ + 'image' => ['nullable', 'image'], + ]; + } +} +``` + +Now the only thing we need to do is include the title: + +```php +$postData->include('posts.title')->toJson(); +``` + +Which will result in this JSON: + +```json +{ + "name" : "Ruben Van Assche", + "posts" : [ + { + "title" : "Hello laravel-data" + } + ] +} +``` + +If we also want to include the status, we can do the following: + +```php +$postData->include('posts.{title,status}')->toJson(); +``` + +It is also possible to include all properties of the posts like this: + +```php +$postData->include('posts.*')->toJson(); +``` + +You can do quite a lot with lazy properties like including them: + +- when a model relation is loaded like Laravel API resources +- when they are requested in the URL query +- by default, with an option to exclude them + +And a lot more. You can read all about it [here](/docs/laravel-data/v4/as-a-resource/lazy-properties). + +## Conclusion + +So that's it, a quick overview of this package. We barely scratched the surface of what's possible with the package. There's still a lot more you can do with data objects like: + +- [casting](/docs/laravel-data/v4/advanced-usage/eloquent-casting) them into Eloquent models +- [transforming](/docs/laravel-data/v4/advanced-usage/typescript) the structure to typescript +- [working](/docs/laravel-data/v4/as-a-data-transfer-object/collections) with `DataCollections` +- [optional properties](/docs/laravel-data/v4/as-a-data-transfer-object/optional-properties) not always required when creating a data object +- [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping) transformed data into keys +- [mapping](/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names) property names when creating or transforming a data object +- [appending](/docs/laravel-data/v4/as-a-resource/appending-properties) extra data +- [including](/docs/laravel-data/v4/as-a-resource/lazy-properties#content-using-query-strings) properties using the URL query string +- [inertia](https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-inertia) support for lazy properties +- and so much more ... you'll find all the information here in the docs + +]]> + + +<_index_md> + + + + DATE_ATOM, + + /* + * When transforming or casting dates, the following timezone will be used to + * convert the date to the correct timezone. If set to null no timezone will + * be passed. + */ + 'date_timezone' => null, + + /* + * It is possible to enable certain features of the package, these would otherwise + * be breaking changes, and thus they are disabled by default. In the next major + * version of the package, these features will be enabled by default. + */ + 'features' => [ + 'cast_and_transform_iterables' => false, + + /* + * When trying to set a computed property value, the package will throw an exception. + * You can disable this behaviour by setting this option to true, which will then just + * ignore the value being passed into the computed property and recalculate it. + */ + 'ignore_exception_when_trying_to_set_computed_property_value' => false, + ], + + /* + * Global transformers will take complex types and transform them into simple + * types. + */ + 'transformers' => [ + DateTimeInterface::class => \Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer::class, + \Illuminate\Contracts\Support\Arrayable::class => \Spatie\LaravelData\Transformers\ArrayableTransformer::class, + BackedEnum::class => Spatie\LaravelData\Transformers\EnumTransformer::class, + ], + + /* + * Global casts will cast values into complex types when creating a data + * object from simple types. + */ + 'casts' => [ + DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, + BackedEnum::class => Spatie\LaravelData\Casts\EnumCast::class, +// Enumerable::class => Spatie\LaravelData\Casts\EnumerableCast::class, + ], + + /* + * Rule inferrers can be configured here. They will automatically add + * validation rules to properties of a data object based upon + * the type of the property. + */ + 'rule_inferrers' => [ + Spatie\LaravelData\RuleInferrers\SometimesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\NullableRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\RequiredRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\BuiltInTypesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\AttributesRuleInferrer::class, + ], + + /* + * Normalizers return an array representation of the payload, or null if + * it cannot normalize the payload. The normalizers below are used for + * every data object, unless overridden in a specific data object class. + */ + 'normalizers' => [ + Spatie\LaravelData\Normalizers\ModelNormalizer::class, + // Spatie\LaravelData\Normalizers\FormRequestNormalizer::class, + Spatie\LaravelData\Normalizers\ArrayableNormalizer::class, + Spatie\LaravelData\Normalizers\ObjectNormalizer::class, + Spatie\LaravelData\Normalizers\ArrayNormalizer::class, + Spatie\LaravelData\Normalizers\JsonNormalizer::class, + ], + + /* + * Data objects can be wrapped into a key like 'data' when used as a resource, + * this key can be set globally here for all data objects. You can pass in + * `null` if you want to disable wrapping. + */ + 'wrap' => null, + + /* + * Adds a specific caster to the Symphony VarDumper component which hides + * some properties from data objects and collections when being dumped + * by `dump` or `dd`. Can be 'enabled', 'disabled' or 'development' + * which will only enable the caster locally. + */ + 'var_dumper_caster_mode' => 'development', + + /* + * It is possible to skip the PHP reflection analysis of data objects + * when running in production. This will speed up the package. You + * can configure where data objects are stored and which cache + * store should be used. + * + * Structures are cached forever as they'll become stale when your + * application is deployed with changes. You can set a duration + * in seconds if you want the cache to clear after a certain + * timeframe. + */ + 'structure_caching' => [ + 'enabled' => true, + 'directories' => [app_path('Data')], + 'cache' => [ + 'store' => env('CACHE_STORE', env('CACHE_DRIVER', 'file')), + 'prefix' => 'laravel-data', + 'duration' => null, + ], + 'reflection_discovery' => [ + 'enabled' => true, + 'base_path' => base_path(), + 'root_namespace' => null, + ], + ], + + /* + * A data object can be validated when created using a factory or when calling the from + * method. By default, only when a request is passed the data is being validated. This + * behaviour can be changed to always validate or to completely disable validation. + */ + 'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::OnlyRequests->value, + + /* + * A data object can map the names of its properties when transforming (output) or when + * creating (input). By default, the package will not map any names. You can set a + * global strategy here, or override it on a specific data object. + */ + 'name_mapping_strategy' => [ + 'input' => null, + 'output' => null, + ], + + /* + * When using an invalid include, exclude, only or except partial, the package will + * throw an exception. You can disable this behaviour by setting this option to true. + */ + 'ignore_invalid_partials' => false, + + /* + * When transforming a nested chain of data objects, the package can end up in an infinite + * loop when including a recursive relationship. The max transformation depth can be + * set as a safety measure to prevent this from happening. When set to null, the + * package will not enforce a maximum depth. + */ + 'max_transformation_depth' => null, + + /* + * When the maximum transformation depth is reached, the package will throw an exception. + * You can disable this behaviour by setting this option to true which will return an + * empty array. + */ + 'throw_when_max_transformation_depth_reached' => true, + + /* + * When using the `make:data` command, the package will use these settings to generate + * the data classes. You can override these settings by passing options to the command. + */ + 'commands' => [ + + /* + * Provides default configuration for the `make:data` command. These settings can be overridden with options + * passed directly to the `make:data` command for generating single Data classes, or if not set they will + * automatically fall back to these defaults. See `php artisan make:data --help` for more information + */ + 'make' => [ + + /* + * The default namespace for generated Data classes. This exists under the application's root namespace, + * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the + * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. + */ + 'namespace' => 'Data', + + /* + * This suffix will be appended to all data classes generated by make:data, so that they are less likely + * to conflict with other related classes, controllers or models with a similar name without resorting + * to adding an alias for the Data object. Set to a blank string (not null) to disable. + */ + 'suffix' => 'Data', + ], + ], + + /* + * When using Livewire, the package allows you to enable or disable the synths + * these synths will automatically handle the data objects and their + * properties when used in a Livewire component. + */ + 'livewire' => [ + 'enable_synths' => false, + ], +]; +``` + +]]> + + + + Latest Version + Software License + Total Downloads + + +]]> + + + + + + + + + + + + + + + + ['required', 'string'], + 'age' => ['required', 'integer'], + 'genre' => ['nullable', 'string'], +] +``` + +All these rules are inferred by `RuleInferrers`, special classes that will look at the types of properties and will add rules based upon that. + +Rule inferrers are configured in the `data.php` config file: + +```php +/* + * Rule inferrers can be configured here. They will automatically add + * validation rules to properties of a data object based upon + * the type of the property. + */ +'rule_inferrers' => [ + Spatie\LaravelData\RuleInferrers\SometimesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\NullableRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\RequiredRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\BuiltInTypesRuleInferrer::class, + Spatie\LaravelData\RuleInferrers\AttributesRuleInferrer::class, +], +``` + +By default, five rule inferrers are enabled: + +- **SometimesRuleInferrer** will add a `sometimes` rule when the property is optional +- **NullableRuleInferrer** will add a `nullable` rule when the property is nullable +- **RequiredRuleInferrer** will add a `required` rule when the property is not nullable +- **BuiltInTypesRuleInferrer** will add a rules which are based upon the built-in php types: + - An `int` or `float` type will add the `numeric` rule + - A `bool` type will add the `boolean` rule + - A `string` type will add the `string` rule + - A `array` type will add the `array` rule +- **AttributesRuleInferrer** will make sure that rule attributes we described above will also add their rules + +It is possible to write your rule inferrers. You can find more information [here](/docs/laravel-data/v4/advanced-usage/creating-a-rule-inferrer). + +]]> + +<_index_md> + + + + 'Never gonna give you up'] +); // ValidationException will be thrown because 'artist' is missing +``` + +When you also want to create the object after validation was successful you can use `validateAndCreate`: + +```php +SongData::validateAndCreate( + ['title' => 'Never gonna give you up', 'artist' => 'Rick Astley'] +); // returns a SongData object +``` + +### Validate everything + +It is possible to validate all payloads injected or passed to the `from` method by setting the `validation_strategy` config option to `Always`: + +```php +'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::Always->value, +``` + +Completely disabling validation can be done by setting the `validation_strategy` config option to `Disabled`: + +```php +'validation_strategy' => \Spatie\LaravelData\Support\Creation\ValidationStrategy::Disabled->value, +``` + +If you require a more fine-grained control over when validation should happen, you can use [data factories](/docs/laravel-data/v4/as-a-data-transfer-object/factories) to manually specify the validation strategy. + +## A quick glance at the validation functionality + +We've got a lot of documentation about validation and we suggest you read it all, but if you want to get a quick glance at the validation functionality, here's a quick overview: + +### Auto rule inferring + +The package will automatically infer validation rules from the data object. For example, for the following data class: + +```php +class ArtistData extends Data{ + public function __construct( + public string $name, + public int $age, + public ?string $genre, + ) { + } +} +``` + +The package will generate the following validation rules: + +```php +[ + 'name' => ['required', 'string'], + 'age' => ['required', 'integer'], + 'genre' => ['nullable', 'string'], +] +``` + +The package follows an algorithm to infer rules from the data object. You can read more about it [here](/docs/laravel-data/v4/validation/auto-rule-inferring). + +### Validation attributes + +It is possible to add extra rules as attributes to properties of a data object: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(20)] + public string $artist, + ) { + } +} +``` + +When you provide an artist with a length of more than 20 characters, the validation will fail. + +There's a complete [chapter](/docs/laravel-data/v4/validation/using-validation-attributes) dedicated to validation attributes. + +### Manual rules + +Sometimes you want to add rules manually, this can be done as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['required', 'string'], + 'artist' => ['required', 'string'], + ]; + } +} +``` + +You can read more about manual rules in its [dedicated chapter](/docs/laravel-data/v4/validation/manual-rules). + +### Using the container + +You can resolve a data object from the container. + +```php +app(SongData::class); +``` + +We resolve a data object from the container, its properties will already be filled by the values of the request with matching key names. +If the request contains data that is not compatible with the data object, a validation exception will be thrown. + +### Working with the validator + +We provide a few points where you can hook into the validation process. You can read more about it in the [dedicated chapter](/docs/laravel-data/v4/validation/working-with-the-validator). + +It is for example to: + +- overwrite validation messages & attributes +- overwrite the validator itself +- overwrite the redirect when validation fails +- allow stopping validation after a failure +- overwrite the error bag + +### Authorizing a request + +Just like with Laravel requests, it is possible to authorize an action for certain people only: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function authorize(): bool + { + return Auth::user()->name === 'Ruben'; + } +} +``` + +If the method returns `false`, then an `AuthorizationException` is thrown. + +## Validation of nested data objects + +When a data object is nested inside another data object, the validation rules will also be generated for that nested object. + +```php +class SingleData{ + public function __construct( + public ArtistData $artist, + public SongData $song, + ) { + } +} +``` + +The validation rules for this class will be: + +```php +[ + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], + 'artist.genre' => ['nullable', 'string'], + 'song' => ['array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['required', 'string'], +] +``` + +There are a few quirky things to keep in mind when working with nested data objects, you can read all about it [here](/docs/laravel-data/v4/validation/nesting-data). + +## Validation of nested data collections + +Let's say we want to create a data object like this from a request: + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +Since the `SongData` has its own validation rules, the package will automatically apply them when resolving validation +rules for this object. + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` + +More info about nested data collections can be found [here](/docs/laravel-data/v4/validation/nesting-data). + +## Default values + +When you've set some default values for a data object, the validation rules will only be generated if something else than the default is provided. + +For example, when we have this data object: + +```php +class SongData extends Data +{ + public function __construct( + public string $title = 'Never Gonna Give You Up', + public string $artist = 'Rick Astley', + ) { + } +} +``` + +And we try to validate the following data: + +```php +SongData::validate( + ['title' => 'Giving Up On Love'] +); +``` + +Then the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], +] +``` + +## Mapping property names + +When mapping property names, the validation rules will be generated for the mapped property name: + +```php +class SongData extends Data +{ + public function __construct( + #[MapInputName('song_title')] + public string $title, + ) { + } +} +``` + +The validation rules for this class will be: + +```php +[ + 'song_title' => ['required', 'string'], +] +``` + +There's one small catch when the validation fails; the error message will be for the original property name, not the mapped property name. This is a small quirk we hope to solve as soon as possible. + +## Retrieving validation rules for a data object + +You can retrieve the validation rules a data object will generate as such: + +```php +AlbumData::getValidationRules($payload); +``` + +This will produce the following array with rules: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'songs.*.title' => ['required', 'string'], + 'songs.*.artist' => ['required', 'string'], +] +``` + +### Payload requirement + +We suggest always providing a payload when generating validation rules. Because such a payload is used to determine which rules will be generated and which can be skipped. + +]]> + + + ['required', 'string'], + 'artist' => ['required', 'string'], + ]; + } +} +``` + +By overwriting a property's rules within the `rules` method, no other rules will be inferred automatically anymore for that property. + +This means that in the following example, only a `max:20` rule will be added, and not a `string` and `required` rule: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['max:20'], + 'artist' => ['max:20'], + ]; + } +} + +// The generated rules will look like this +[ + 'title' => ['max:20'], + 'artist' => ['max:20'], +] +``` + +As a rule of thumb always follow these rules: + +Always use the array syntax for defining rules and not a single string which spits the rules by | characters. +This is needed when using regexes those | can be seen as part of the regex + +## Merging manual rules + +Writing manual rules doesn't mean that you can't use the automatic rules inferring anymore. By adding the `MergeValidationRules` attribute to your data class, the rules will be merged: + +```php +#[MergeValidationRules] +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => ['max:20'], + 'artist' => ['max:20'], + ]; + } +} + +// The generated rules will look like this +[ + 'title' => [required, 'string', 'max:20'], + 'artist' => [required, 'string', 'max:20'], +] +``` + +## Using attributes + +It is even possible to use the validationAttribute objects within the `rules` method: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(): array + { + return [ + 'title' => [new Required(), new StringType()], + 'artist' => [new Required(), new StringType()], + ]; + } +} +``` + +You can even add dependencies to be automatically injected: + +```php +use SongSettingsRepository; + +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(SongSettingsRepository $settings): array + { + return [ + 'title' => [new RequiredIf($settings->forUser(auth()->user())->title_required), new StringType()], + 'artist' => [new Required(), new StringType()], + ]; + } +} +``` + +## Using context + +Sometimes a bit more context is required, in such a case a `ValidationContext` parameter can be injected as such: +Additionally, if you need to access the data payload, you can use `$payload` parameter: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'title' => ['required'], + 'artist' => Rule::requiredIf($context->fullPayload['title'] !== 'Never Gonna Give You Up'), + ]; + } +} +``` + +By default, the provided payload is the whole request payload provided to the data object. +If you want to generate rules in nested data objects, then a relative payload can be more useful: + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} + +class SongData extends Data +{ + public function __construct( + public string $title, + public ?string $artist, + ) { + } + + public static function rules(ValidationContext $context): array + { + return [ + 'title' => ['required'], + 'artist' => Rule::requiredIf($context->payload['title'] !== 'Never Gonna Give You Up'), + ]; + } +} +``` + +When providing such a payload: + +```php +[ + 'title' => 'Best songs ever made', + 'songs' => [ + ['title' => 'Never Gonna Give You Up'], + ['title' => 'Heroes', 'artist' => 'David Bowie'], + ], +]; +``` + +The rules will be: + +```php +[ + 'title' => ['string', 'required'], + 'songs' => ['present', 'array'], + 'songs.*.title' => ['string', 'required'], + 'songs.*.artist' => ['string', 'nullable'], + 'songs.*' => [NestedRules(...)], +] +``` + +It is also possible to retrieve the current path in the data object chain we're generating rules for right now by calling `$context->path`. In the case of our previous example this would be `songs.0` and `songs.1`; + +Make sure the name of the parameter is `$context` in the `rules` method, otherwise no context will be injected. + +]]> + + + ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +## Validating a nested collection of data objects + +When validating a data object like this + +```php +class AlbumData extends Data +{ + /** + * @param array $songs + */ + public function __construct( + public string $title, + public array $songs, + ) { + } +} +``` + +In this case the validation rules for `AlbumData` would look like this: + +```php +[ + 'title' => ['required', 'string'], + 'songs' => ['present', 'array', new NestedRules()], +] +``` + +The `NestedRules` class is a Laravel validation rule that will validate each item within the collection for the rules defined on the data class for that collection. + +## Nullable and Optional nested data + +If we make the nested data object nullable, the validation rules will change depending on the payload provided: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ?ArtistData $artist, + ) { + } +} +``` + +If no value for the nested object key was provided or the value is `null`, the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['nullable'], +] +``` + +If, however, a value was provided (even an empty array), the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +The same happens when a property is made optional: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $title, + public ArtistData $artist, + ) { + } +} +``` + +There's a small difference compared against nullable, though. When no value was provided for the nested object key, the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['present', 'array', new NestedRules()], +] +``` + +However, when a value was provided (even an empty array or null), the validation rules will be: + +```php +[ + 'title' => ['required', 'string'], + 'artist' => ['array'], + 'artist.name' => ['required', 'string'], + 'artist.age' => ['required', 'integer'], +] +``` + +We've written a [blog post](https://flareapp.io/blog/fixing-nested-validation-in-laravel) on the reasoning behind these variable validation rules based upon payload. And they are also the reason why calling `getValidationRules` on a data object always requires a payload to be provided. + +]]> + + +input('first_name')} {$request->input('last_name')}") + } + + public static function rules(): array + { + return [ + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], + ]; + } +} +``` + +When a request is being validated, the rules will look like this: + +```php +[ + 'name' => ['required', 'string'], + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], +] +``` + +We know we never want to validate the `name` property since it won't be in the request payload, this can be done as +such: + +```php +class SongData extends Data +{ + public function __construct( + #[WithoutValidation] + public string $name, + ) { + } +} +``` + +Now the validation rules will look like this: + +```php +[ + 'first_name' => ['required', 'string'], + 'last_name' => ['required', 'string'], +] +``` + +## Skipping validation for all properties + +By using [data factories](/docs/laravel-data/v4/as-a-data-transfer-object/factories) or setting the `validation_strategy` in the `data.php` config you can skip validation for all properties of a data class. + +]]> + + + ['required', 'string', 'uuid'], + 'ip' => ['required', 'string', 'max:15', 'ip', 'starts_with:192.'], +] +``` + +For each Laravel validation rule we've got a matching validation attribute, you can find a list of +them [here](/docs/laravel-data/v4/advanced-usage/validation-attributes). + +## Referencing route parameters + +Sometimes you need a value within your validation attribute which is a route parameter. +Like the example below where the id should be unique ignoring the current id: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Unique('songs', ignore: new RouteParameterReference('song'))] + public int $id, + ) { + } +} +``` + +If the parameter is a model and another property should be used, then you can do the following: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Unique('songs', ignore: new RouteParameterReference('song', 'uuid'))] + public string $uuid, + ) { + } +} +``` + +## Referencing the current authenticated user + +If you need to reference the current authenticated user in your validation attributes, you can use the +`AuthenticatedUserReference`: + +```php +use Spatie\LaravelData\Support\Validation\References\AuthenticatedUserReference; + +class UserData extends Data +{ + public function __construct( + public string $name, + #[Unique('users', 'email', ignore: new AuthenticatedUserReference())] + public string $email, + ) { + } +} +``` + +When you need to reference a specific property of the authenticated user, you can do so like this: + +```php +class SongData extends Data +{ + public function __construct( + #[Max(new AuthenticatedUserReference('max_song_title_length'))] + public string $title, + ) { + } +} +``` + +Using a different guard than the default one can be done by passing the guard name to the constructor: + +```php +class UserData extends Data +{ + public function __construct( + public string $name, + #[Unique('users', 'email', ignore: new AuthenticatedUserReference(guard: 'api'))] + public string $email, + ) { + } +} +``` + +## Referencing container dependencies + +If you need to reference a container dependency in your validation attributes, you can use the `ContainerReference`: + +```php +use Spatie\LaravelData\Support\Validation\References\ContainerReference; + +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference('max_song_title_length'))] + public string $artist, + ) { + } +} +``` + +It might be more useful to use a property of the container dependency, which can be done like this: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length'))] + public string $artist, + ) { + } +} +``` + +When your dependency requires specific parameters, you can pass them along: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length', parameters: ['repository' => 'redis']))] + public string $artist, + ) { + } +} +``` + +## Referencing other fields + +It is possible to reference other fields in validation attributes: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[RequiredIf('title', 'Never Gonna Give You Up')] + public string $artist, + ) { + } +} +``` + +These references are always relative to the current data object. So when being nested like this: + +```php +class AlbumData extends Data +{ + public function __construct( + public string $album_name, + public SongData $song, + ) { + } +} +``` + +The generated rules will look like this: + +```php +[ + 'album_name' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['string', 'required_if:song.title,"Never Gonna Give You Up"'], +] +``` + +If you want to reference fields starting from the root data object you can do the following: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + #[RequiredIf(new FieldReference('album_name', fromRoot: true), 'Whenever You Need Somebody')] + public string $artist, + ) { + } +} +``` + +The rules will now look like this: + +```php +[ + 'album_name' => ['required', 'string'], + 'songs' => ['required', 'array'], + 'song.title' => ['required', 'string'], + 'song.artist' => ['string', 'required_if:album_name,"Whenever You Need Somebody"'], +] +``` + +## Rule attribute + +One special attribute is the `Rule` attribute. With it, you can write rules just like you would when creating a custom +Laravel request: + +```php +// using an array +#[Rule(['required', 'string'])] +public string $property + +// using a string +#[Rule('required|string')] +public string $property + +// using multiple arguments +#[Rule('required', 'string')] +public string $property +``` + +## Creating your validation attribute + +It is possible to create your own validation attribute by extending the `CustomValidationAttribute` class, this class +has a `getRules` method that returns the rules that should be applied to the property. + +```php +#[Attribute(Attribute::TARGET_PROPERTY | Attribute::TARGET_PARAMETER)] +class CustomRule extends CustomValidationAttribute +{ + /** + * @return array|object|string + */ + public function getRules(ValidationPath $path): array|object|string + { + return [new CustomRule()]; + } +} +``` + +Quick note: you can only use these rules as an attribute, not as a class rule within the static `rules` method of the +data class. + +]]> + + + 'A title is required', + 'artist.required' => 'An artist is required', + ]; + } +} +``` + +## Overwriting attributes + +In the default Laravel validation rules, you can overwrite the name of the attribute as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function attributes(): array + { + return [ + 'title' => 'titel', + 'artist' => 'artiest', + ]; + } +} +``` + +## Overwriting other validation functionality + +Next to overwriting the validator, attributes and messages it is also possible to overwrite the following functionality. + +The redirect when a validation failed: + +```php +class SongData extends Data +{ + // ... + + public static function redirect(): string + { + return action(HomeController::class); + } +} +``` + +Or the route which will be used to redirect after a validation failed: + +```php +class SongData extends Data +{ + // ... + + public static function redirectRoute(): string + { + return 'home'; + } +} +``` + +Whether to stop validating on the first failure: + +```php +class SongData extends Data +{ + // ... + + public static function stopOnFirstFailure(): bool + { + return true; + } +} +``` + +The name of the error bag: + +```php +class SongData extends Data +{ + // ... + + public static function errorBag(): string + { + return 'never_gonna_give_an_error_up'; + } +} +``` + +### Using dependencies in overwritten functionality + +You can also provide dependencies to be injected in the overwritten validator functionality methods like `messages` +, `attributes`, `redirect`, `redirectRoute`, `stopOnFirstFailure`, `errorBag`: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function attributes( + ValidationAttributesLanguageRepository $validationAttributesLanguageRepository + ): array + { + return [ + 'title' => $validationAttributesLanguageRepository->get('title'), + 'artist' => $validationAttributesLanguageRepository->get('artist'), + ]; + } +} +``` + +## Overwriting the validator + +Before validating the values, it is possible to plugin into the validator. This can be done as such: + +```php +class SongData extends Data +{ + public function __construct( + public string $title, + public string $artist, + ) { + } + + public static function withValidator(Validator $validator): void + { + $validator->after(function ($validator) { + $validator->errors()->add('field', 'Something is wrong with this field!'); + }); + } +} +``` + +Please note that this method will only be called on the root data object that is being validated, all the nested data objects and collections `withValidator` methods will not be called. + +]]> + + +