# Salt Edge Inc. функционал для Openbanking регулирования
## Авторизация пользователя:
TKS документация https://tkn-internal.paxum.com/api/doc.json
1. Пользователь видит экран авторизации, где ему необходимо ввести логин и пароль.
2. Пользователь вводит данные и нажимает кнопку 'Login':
2.1. Если у пользователя включен Strong Customer Protection по пушу, то ему необходимо показать показать окно с названиями утроств и показать QR код и ждать пока из Центрифуги прилетит Код для дальнейшей авторизации. *(Уже реализовано в продакшене)*
2.2. Если у пользователя не включён Strong Customer Protection, но есть подтверждённый номер телефона, то надо отобразить последние 2 цифры номера телефона и идентификатор кода и ждать пока пользователь подвердит 6 значным кодом из СМС. *(По аналогии с текущим OTP флоу)*
2.3. Если у пользователя нет возможности подтвердить 2FA, то его необходимо перенаправить из нашего прилоежения.
3. Получить токены доступа и войти в приложение.
#### Примеры:
##### 2. Логин
```
POST /v4/auth/login
```
```json
{
"client": "sei",
"username": "string",
"password": "string",
"codeChallenge": "FZmNn3lxCOralJSPSPTPAZBap_lZLnnueSdR5PJ8En8"
}
```
:::spoiler Подсказка
Параметр `client` обязательно должен равняться `sei`.
Параметр `codeChallenge` заполняется утилитой PKCE, которая уже есть во фронтовом проекте.
:::
##### 2.1. Респонс для подтверждения по пушу
```
Response code is 201 (HTTP_CREATED)
```
```json
{
"authFlow": "push",
"tmpJwt": "string",
"devices": ["string", "string"],
"link": "pdk://deeplink.flutter.dev/params?bla=bla",
"exp": 1660214106
}
```
Событие, которое ожидается в вебсокете:
```json
{
type: "AuthConfirmation",
result: true,
code: "def5020044349ecea97393173570ffd692f4ce18b8161142a1c14212789e209838464ca5c86880d212f91e6b8220fdb9e096c38e2b1160bedc5d3f7477be463f74d9ca200dbbd9fdfd8cd29575140c3def12f54bb43f1c6c0741f54e6f75028955cd9d2084ee546d8a5ce59b5937260075256539a0e6954e3c66f2d087ad724a0ffd33edd8c2a581adf43805e63b26ac33ad46e5524420f62b89ffb2dea77238d153701848f2c70820d3e4498b"
}
```
:::spoiler Подсказка
`result` Может быть `false`, тогда `code` не придёт, надо будет перенаправить пользователя из нашей системы.
`link` должно быть преорабразовано в QR код и показано пользователю.
:::
##### 2.2. Респонс для подтверждения по смс
```
Response code is 201 (HTTP_CREATED)
```
```json
{
"authFlow": "sms",
"code": "def5020044349ecea97393173570ffd692f4ce18b8161142a1c14212789e209838464ca5c86880d212f91e6b8220fdb9e096c38e2b1160bedc5d3f7477be463f74d9ca200dbbd9fdfd8cd29575140c3def12f54bb43f1c6c0741f54e6f75028955cd9d2084ee546d8a5ce59b5937260075256539a0e6954e3c66f2d087ad724a0ffd33edd8c2a581adf43805e63b26ac33ad46e5524420f62b89ffb2dea77238d153701848f2c70820d3e4498b",
"codeTtl": 600,
"smsIdentifier": "09",
"phoneNumber": "******67"
}
```
:::spoiler Подсказка
Далее ожидается, что пользователь введёт 6 цифр из смс и войдёт в систему.
:::
##### 2.3. Респонс, когда 2FA не возможен
```
Response code is 403 (HTTP_FORBIDDEN)
```
```json
{
"message": "Strong customer protection is disabled. Please double-check SCA settings and try again."
}
```
##### 3. Получение токенов доступа или редирект пользователя из системы.
```
POST /v4/auth/token
```
```json
{
"code": "string",
"codeVerifier": "PFJa3THClb-HhI6Vf5ECH4Mn9I96WImgGq-z02jNVnh46i3bcFbv225sQopD8vcSe6RlPUxrYrTk8nNbc4nMPUSrb2vPV4LbNYfa8syHOH~R90qXgw3hbJQV1IMITHHi",
"otp": "string" | null
}
```
:::spoiler Подсказка
Параметр `code` взят из предыдущего шага.
Параметр `codeVerifier` заполняется утилитой PKCE, которая уже есть во фронтовом проекте.
Параметр `otp` заполняется кодом из смс для SMS флоу.
:::
##### Если пользователю не удалось авторизоваться и требуется его перенаправить из системы
```
POST /v4/auth/sei/authorize
```
```json
{
"authorizeUrl": "https://portal.paydek.com/auth/sei?bla=bla"
}
```
P.S. Отправить этот запрос не авторизованным.
**Респонс:**
```json
{
"payload": {
"redirect_uri": "https://priora-demo.saltedge.com/openbanking/authorizations/callback?error=access_denied&error_message=User+denied+the+authorization&state=bb0e3c3f26bdbd47de4417deaeaf8e13aca96591a4c551f754b7eb27aee37068"
}
}
```
## Целевой функционал
1. После получения токенов доступа, необходимо по одному из трёх флоу redirect, ais, pis. *(ais флоу должен быть уже реализован на фронте)*
2. Отправить авторизованный запрос на создание consent'а.
2.1. Если редирект флоу, то пользователя надо просто перенаправить из системы.
2.2. Если флоу AIS, то надо показать пользователю его аккаунты с балансами (balanceInquiry) с возможностью выбора нужных и двумя кнопками "Allow" и "Reject". После чего перенаправить пользователя из системы.
2.3. Если флоу PIS, то необходимо показать пользователю сведения о транзакции и выбор аккаунта списания и две кнопки "Allow" и "Reject", но кнопки задизейблены, пока он не выбрал аккаунт с которого надо списать. После чего перенаправить пользователя из системы.
#### Примеры:
##### 2. Отправить запрос с JWT токеном на создание consent'а
```
POST /v4/auth/sei/authorize
```
```json
{
"authorizeUrl": "https://portal.paydek.com/auth/sei?bla=bla"
}
```
:::spoiler Подсказка
URI целиком с которым пользователь редиректнулся к нам в систему.
:::
##### 2.1. Респонс для редирект флоу
```
Response code is 201 (HTTP_CREATED)
```
```json
{
"payload": {
"redirect_uri": "https://priora-demo.saltedge.com/openbanking/authorizations/callback?error=access_denied&error_message=User+denied+the+authorization&state=bb0e3c3f26bdbd47de4417deaeaf8e13aca96591a4c551f754b7eb27aee37068"
}
}
```
:::spoiler Подсказка
Salt edge забыли положить параметр с флоу, поэтому стоит ориентироваться по параметру `payload.redirect_uri`, если он есть, то просто редиректим пользователя.
:::
##### 2.2. Респонс для AIS флоу
```
Response code is 201 (HTTP_CREATED)
```
```json
{
"payload": {
"app_name": "Priora Demo",
"flow_type": "ais",
"authorization_id": 262
}
}
```
:::spoiler Подсказка
authorization_id - это и есть Consent ID. В форме выбора должно присутствовать имя приложения, которое запрашивает доступы.
:::
После выбора пользователем аккаунтов, надо отправить следующий метод:
```
PATCH /v4/auth/sei/authorize/{authorization_id}
```
```json
{
"result": true,
"flow": "ais",
"payload": {
"access": ["745975"]
}
}
```
:::spoiler Подсказка
В параметр `payload.access` кладутся ID'шники всех аккаунтов, которые выбрал пользователь.
Если `result` = `false`, то `payload` отправлять не надо.
:::
```
Response code is 200 (HTTP_OK)
```
```json
{
"payload": {
"redirect_uri": "https://priora-demo.saltedge.com/openbanking/authorizations/callback?code=615d19fe-dc07-4653-a7a1-dc504099f956&state=df144adc310534233068f7fa73b5715ad8e4ba41c98b13827bf03d4c42f34fab&scope=openid%20accounts%20payments",
"status": "approved"
}
}
```
:::spoiler Подсказка
Просто редиректим пользователя.
:::
##### 2.3. Респонс для PIS флоу
```
Response code is 201 (HTTP_CREATED)
```
```json
{
"payload": {
"app_name": "Priora Demo",
"flow_type": "pis",
"authorization_id": 263,
"payment_details": {
"payment_type": "international_payment",
"instructed_amount": {
"amount": "1000",
"currency": "USD"
},
"creditor_account": {
"name": "Lolkek",
"scheme_name": "UK.OBIE.BBAN",
"identification": "123"
}
}
}
}
```
:::spoiler Подсказка
authorization_id - это и есть Consent ID. В форме выбора должно присутствовать имя приложения, которое запрашивает доступы.
Эти данные надо показать пользователю и дать две кнопки "Allow" и "Reject".
:::
Решение пользователя надо отправить на следующий метод:
```
PATCH /v4/auth/sei/authorize/{authorization_id}
```
```json
{
"result": true,
"flow": "pis",
"payload": {
"user_name": "Albert Shtein",
"debtor_account": {
"identification": "745975", // Chosen account ID
"scheme_name": "UK.Paydek.AccountIdentifier",
"name": "USD Account"
}
}
}
```
:::spoiler Подсказка
В ответ в любом случае должен возвращаться `redirect_uri`.
:::
```
Response code is 200 (HTTP_OK)
```
```json
{
"payload": {
"redirect_uri": "https://priora-demo.saltedge.com/openbanking/authorizations/callback?code=dd327863-c480-4bdb-ab32-9a3fa885296a&state=af8257b047407b812dcd7818e68c2056749879351ea5bc007140f4c3437a1ffe&scope=openid%20accounts%20payments"
}
}
```
:::spoiler Подсказка
Просто редиректим пользователя.
:::
P.S. Если бэкенд вернул какую-то ошибку отличную от UNAUTHORIZED, то просто выводим её пользователю, пусть живёт с этим. Если UNAUTHORIZED, то рефрешим, если не рефрешится - обратно на логин пейдж.