# 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, то рефрешим, если не рефрешится - обратно на логин пейдж.