Перейти к содержанию

Общие принципы и правила

Статья описывает общие принципы и правила взаимодействия c платформой.

Подтверждение операций

Для обеспечения безопасности и соблюдения регуляторных требований к кредитным организациям клиент должен подтверждать выполнение операций, которые предполагают доступ QIWI к его денежным средствам.

Процесс подтверждения включает три этапа:

На основании успешной аутентификации личности клиента QIWI (BaaS) выпускает клиентский токен, который в дальнейшем используется для авторизации операций.

Процесс подтверждения в упрощённом виде изображён на диаграмме ниже.

%%{init: {
    "sequence" : {
        "messageFontSize":14,
        "noteFontSize":14,
         }}}%%
sequenceDiagram
    participant P as Партнёр
    participant B as BaaS
    critical Выполняется при создании клиента, выпуске карты и др.
    rect rgb(230, 230, 230)
    P->>+B: Сценарий «Аутентификация с помощью OTP»
    Note right of P: OTP
    B-->>-P: 
    Note left of B: confirmationId
    end
    end
    critical Выполняется только один раз при наличии успешной аутентификации
    rect rgb(255, 238, 223)
    P->>+B: Сценарий «Выпуск токена»
    Note right of P: confirmationId
    B-->>-P: 
    Note left of B: tokenValue
    end
    end
    loop Выполняется каждый раз при попытке совершить операцию
    rect rgb(230, 230, 230)
    P->>+B: Сценарий «Авторизация с помощью клиентского токена»
    Note right of P: tokenValue
    B-->>-P: 
    Note left of B: status:SUCCESS
    end
    end

Аутентификация с помощью OTP

При выполнении базовых банковских сценариев, таких как создание учётной записи клиента и выпуск карты, клиенту необходимо подтвердить свою личность. QIWI аутентифицирует клиента с помощью OTP.

Последовательность действий для аутентификации с помощью OTP изображена на диаграмме ниже. Этап, на котором эту последовательность необходимо выполнить, см. в статьях c описанием каждого отдельного сценария.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":14,
        "noteFontSize":12,
        "actorMargin":
        125 }}}%%
sequenceDiagram
    participant С as Клиент
    participant P as Партнёр
    participant B as BaaS
    Note left of P: Партнёр получил номер телефона клиента на одном из этапов информационного взаимодействия
    P->>+B: Запрос на отправку OTP
    Note over P,B: productId, clientId, confirmationId:confirm1, confirmationType:SMS, confirmationOperationType, phoneNumber
    B->>-P: 
    Note over P,B: confirmationId:confirm1, resendAttemptsLeft, resendDelaySeconds, confirmationStatus:CREATED
    B->>С: SMS c OTP
    С->>P: Ввод OTP
    Note right of С: 123456
    P->>+B: Запрос на подтверждение OTP
    Note over P,B: productId, clientId, confirmationId:confirm1, confirmationCode:123456
    B->>-P: 
    Note over P,B: confirmationId:confirm1, confirmationStatus:CONFIRMED

Запросы описаны в документации Clients API.

Запрос на отправку OTP выполняется для определённого типа операции, описание см. в таблице ниже.

Сценарий Тип операции в запросе на отправку OTP
Создание клиента CREATE_TOKEN
Выпуск виртуальной карты ORDER_VIRTUAL_CARD
Изменение номера телефона клиента • CHANGE_PHONE_CONFIRM_OLD — для запроса на подтверждение текущего номера;
• CHANGE_PHONE_CONFIRM_NEW — для запроса на подтверждение нового номера
Перевыпуск токена REFRESH_TOKEN
Получение токена GET_TOKEN

Обратите внимание

Актуальный список типов операций см. в документации Clients API. Таблица выше приведена в качестве примера.

В ответе на запрос отправки OTP возвращаются:

  • количество оставшихся запросов на повторную отправку OTP — resendAttemptsLeft;
  • время, через которое можно запросить повторную отправку OTPresendDelaySeconds.

Сценарий «Аутентификация с помощью OTP» можно пройти в тестовой среде. Для этого необходимо:

  • отправлять запросы на URL-адреса тестовой среды;
  • использовать фиксированный набор тестовых данных (см. таблицу ниже).

    Номер телефона OTP
    78000008130 3182
    78000008110 111111

Срок жизни и время использования операции подтверждения

Срок жизни

В результате выполнения запроса на отправку OTP в BaaS создаётся операция подтверждения c идентификатором confirmationId. Эта операция имеет срок жизни — время, в течение которого можно ввести и подтвердить OTP.

Пример

Срок жизни установлен 2 минуты. Клиент получил SMS с OTP. По истечении 2 минут подтвердить этот OTP будет невозможно.

Время использования

В результате успешного подтверждения OTP confirmationId должен быть использован в том сценарии, для которого он создавался. Если партнёр не использовал confirmationId в течение определённого времени с момента подтверждения OTP, успешно завершить сценарий не удастся.

Пример

Время использования установлено 10 минут. Партнёр аутентифицирует клиента, чтобы выпустить для него банковскую карту.

Клиент получил SMS с OTP, в системе партнёра этому OTP соответствует confirmationId:confirm1. Клиент ввёл OTP из SMS в интерфейсе партнёра, OTP подтверждён. По истечении 10 минут создать заказ на выпуск карты c confirmationId:confirm1 будет невозможно.

Жизненный цикл операции подтверждения

flowchart TD
    Start --> CREATED
    Start --> errorCode
    CREATED --> CONFIRMED
    CREATED --> FAILED
    CONFIRMED --> USED

Партнёр отправляет запрос на отправку OTP. BaaS возвращает партнёру один из ответов:

  • HTTP 200 OK и confirmationStatus:CREATED — создана операция подтверждения, OTP успешно отправлен, ожидается аутентификация личности клиента;
  • HTTP 4xx/5xx и errorCode — данные не прошли валидацию или другие внутренние проверки ⇒ операция подтверждения не создана по причине, указанной в errorCode.

Ошибку (errorCode) необходимо интерпретировать согласно справочнику кодов ошибок, обработать и затем возобновить работу с операцией, если ошибка не является фатальной и её можно устранить.

Клиент вводит код из SMS в интерфейсе партнёра, партнёр выполняет запрос на подтверждение OTP для операции в статусе CREATED и операция переходит в один из следующих статусов:

  • CONFIRMED — проверка OTP завершилась успешно, клиент аутентифицирован.
  • FAILED — клиент не аутентифицирован: превышено количество попыток подтверждения или срок жизни истёк.

Если операция в статусе CONFIRMED использована в целевом сценарии в течение заданного времени, её статус меняется на USED. Если не использована — остаётся CONFIRMED.

Одну операцию подтверждения (confirmationId) можно использовать для выполнения целевого сценария только один раз.

Выпуск токена

Клиентский токен используется для авторизации запросов на совершение операций и позволяет BaaS выполнять операции от имени аутентифицированного клиента.

Последовательность действий при создании клиентского токена изображена ниже.

%%{init: {
    "sequence" : {
        "messageFontSize":14,
        "noteFontSize":14,
         }}}%%
sequenceDiagram
    participant P as Партнёр
    participant B as BaaS
    critical Выполняется при создании клиента
    rect rgb(230, 230, 230)
    P->>+B: Сценарий «Аутентификация с помощью OTP»
    Note right of P: confirmationOperationType: CREATE_TOKEN, confirmationId:confirm1
    B-->>-P: 
    end
    end
    P->>+B: Запрос на выпуск токена
    Note right of P: productId, clientId, confirmationId:confirm1
    B->>B: Проверка confirmationId
    Note over B: Клиент аутентифицирован
    B->>-P: 
    Note left of B: tokenValue
    B->>B: Проверка confirmationId

Токен рекомендуется хранить на устройстве клиента: один клиент может иметь множество устройств, но один токен.

Перевыпуск токена

Последовательность действий при перевыпуске клиентского токена изображена ниже.

%%{init: {
    "sequence" : {
        "messageFontSize":14,
        "noteFontSize":14,
         }}}%%
sequenceDiagram
    participant P as Партнёр
    participant B as BaaS
    critical 
    rect rgb(230, 230, 230)
    P->>+B: Сценарий «Аутентификация с помощью OTP»
    Note right of P: confirmationOperationType: REFRESH_TOKEN, confirmationId:confirm2
    B-->>-P: 
    end
    end
    P->>+B: Запрос на выпуск токена
    Note right of P: productId, clientId, confirmationId:confirm2
    B->>B: Проверка confirmationId
    Note over B: Клиент аутентифицирован
    B->>-P: 
    Note left of B: tokenValue

Токен рекомендуется хранить на устройстве клиента: один клиент может иметь множество устройств, но один токен.

Авторизация с помощью клиентского токена

Запрос к API, содержащий заголовок QIWI-Client-Token, требует передачи значения клиентского токена. Чтобы понять, в каких запросах следует передавать QIWI-Client-Token: <значение токена>, см. описание HTTP Headers в документации API.

QIWI-Client-Token является дополнительным фактором авторизации: его использование не отменяет необходимости передавать Bearer Token в заголовке запроса Authorization.

Вычисление цифровой подписи

В процессе информационного взаимодействия с BaaS партнёру может потребоваться вычислить цифровую подпись: например, для перевода средств на банковскую карту с помощью формы или при получении уведомления.

Для вычисления подписи необходимы строковые представления “секрета” (secret) и подписываемых данных, т.е. тела запроса (data). Значение secret предоставляется партнёру по запросу и не зависит от сценария взаимодействия с платформой — оно всегда одинаковое.

Обратите внимание

Необходимо обеспечить надежное хранение secret и не допускать несанкционированный доступ к нему.

Выполните следующие действия:

  • преобразуйте строки secret и data в байты UTF-8 secret_bytes и data_bytes, соответственно;
  • вызовите библиотечную реализацию алгоритма HmacSHA256 для вычисления байтового представления подписи;

    signature_bytes = HmacSHA256(secret_bytes, data_bytes)

  • закодируйте байты подписи в hex-представление и получите строку подписи.

    signature = hex(signature_bytes)

Пример кода на Python
    import hashlib
    import hmac

    data = '{"type":"CLEARING","eventDateTime":"2021-09-20T11:32:35.926795+03:00","txnId":"77fc0beb-1f42-4c46-b4d0-407e3caa13a4","txnType":"FAST_FUNDS","actionId":"ec6861e2-fe67-4d46-a13d-210f5e643e86","actionType":"CAPTURE_FAST_FUNDS","actionStatus":"SUCCESS","actionStatusDetails":{},"actionData":{"cardTokenId":"100080516478","clientId":"547606fd-d5f7-4a60-a004-92fabe246210","clearingDate":"2021-09-20","transactionAmount":{"currency":"RUB","value":"7.89"},"originTransactionAmount":{"currency":"RUB","value":"7.89"},"merchantId":"977492982538","merchantName":"TEST_MERCHANT_NAME","merchantType":"5331","terminalId":"35124585","acquirerId":"357754","wasNotAuthorizedBefore":true}}'
    key = 'cee66da5b04cb4f2026b5c8872dbcf8a'

    key_bytes = bytes(key, 'UTF-8')
    data_bytes = bytes(data, 'UTF-8')
    h = hmac.new(key_bytes, data_bytes, hashlib.sha256 )
    print( h.hexdigest() )
Результат выполнения кода
603ab1c988d87c342d7a2cb2b961cb2fd275a3bd2b97f38c0c36864f29a856fb

Решение об успешности платежа

BaaS поддерживает несколько вариантов проведения платежа:

  • синхронный — когда финальный статус проведения платежа известен сразу и возвращается в ответе на платёжный запрос;
  • асинхронный — когда платёж находится в обработке после получения запроса (и отправки ответа на запрос) и приобретает финальный статус несколько позже.

Синхронный вариант проведения платежа

Пример — выплата на кошелёк, перевод между кошельками и др.

Для принятия решения об успешности платежа партнёр может основываться на значении поля status, полученном в ответе на соответствующий платёжный запрос. Запросы и ответы описаны в документации Payments API.

Последовательность действий для принятия решения об успешности платежа на примере совершения перевода между кошельками приведена ниже.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":14,
        "noteFontSize":14,
        "actorMargin":
        85 }}}%%
sequenceDiagram
    participant С as Клиент
    participant P as Партнёр
    participant B as BaaS
    С->>P: Перевод на кошелёк в интерфейсе
    Note right of С: «Перевести»
    P->>+B: Сценарий «Перевод между кошельками» (Payments API)
    Note right of P: transactionId
    B->>-P: 
    Note left of B: status:SUCCESS
    P->>С: Коммуникация с клиентом

Сценарий «Перевод между кошельками» см. здесь.

Обратите внимание

Синхронный вариант означает, что финальный статус проведения платежа (SUCCESS или DECLINED) известен сразу и возвращается в ответе на платёжный запрос. Тем не менее в редких случаях BaaS может вернуть статус PROCESSING. В такой ситуации партнёр должен выполнять одно из следующих действий до получения финального статуса:

  • отправлять запрос на совершение операции (повторный запрос должен быть идентичен исходному — методы Payments API являются идемпотентными);
  • запрашивать статус операции.

Асинхронный вариант проведения платежа

Пример — пополнение с банковской карты (см. пример запроса), перевод на банковскую карту (см. пример запроса) и др.

Для принятия решения об успешности платежа партнёру нужно дождаться уведомления от BaaS и следовать описанной ниже логике.

Если статус в уведомлении имеет финальное успешное значение status:SUCCESS, партнёру необходимо однократно выполнить запрос статуса к платформе самостоятельно. Это позволит избежать ложных уведомлений, т.е. устранить риски компрометации данных в случае утечки “секрета”, который используется при вычислении цифровой подписи уведомления. В конечном итоге партнёру следует основываться на значении поля status в ответе на запрос статуса соответствующего платежа. Запросы и ответы описаны в документации Payments API.

Последовательность действий для принятия решения об успешности платежа на примере совершения перевода на банковскую карту приведена ниже.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":15,
        "noteFontSize":14,
        "actorMargin":
        85 }}}%%
sequenceDiagram
    participant С as Клиент
    participant P as Партнёр
    participant B as BaaS
    С->>P: Перевод на карту в интерфейсе
    Note right of С: «Перевести»
    P->>+B: Сценарий «Перевод на банковскую карту» (Payments API)
    Note right of P: transactionId
    B->>-P: 
    Note left of B: status:PROCESSING
    rect rgb(255, 238, 223)
    B->>+P: Сценарий «Уведомление об операциях домена PAYMENTS» (History&Notifications API)
    P-->>-B: 
    Note left of B: transactionId, status:SUCCESS
    end
    rect rgb(230, 230, 230)
    P->>+B: Запрос на получение статуса перевода (Payments API)
    Note right of P: transactionId
    B-->>-P: Ответ на запрос получения статуса
    Note left of B: transactionId, status:SUCCESS
    end
    P->>С: Коммуникация с клиентом

Упомянутые на диаграмме сценарии см. в статьях:

Проведение операций домена CARDS

Описание операции домена CARDS см. в статье «Термины и бизнес-сущности». В этом разделе мы расскажем о проведении финансовых операции домена CARDS.

Обработка таких операций условно делится на 2 этапа:

Процесс успешной обработки финансовой операции домена CARDS в упрощённом виде описан ниже.

Онлайн-операция

Здесь описан успешный сценарий обработки финансовой операции домена CARDS.

  1. Клиент совершает операцию — пополняет карту QIWI с карты другого банка, покупает товар или услугу в интернете, снимает наличные в банкомате и др.
  2. Платёжная система, которая обслуживает карту, отправляет QIWI (BaaS) запрос на авторизацию операции.
  3. BaaS совершает действие, которое приводит к движению денежных средств, в рамках запроса на авторизацию — зачисляет средства на баланс клиента, резервирует средства на балансе клиента, списывает их и др.
  4. BaaS создаёт запись об успешном совершении действия в рамках онлайн-операции определённого типа.
  5. BaaS отправляет платёжной системе ответ об успешной авторизации операции.
  6. BaaS отправляет партнёру уведомление об успешном совершении действия в рамках онлайн-операции определённого типа, если такая возможность настроена.

Обратите внимание

В рамках одной и той же онлайн-операции может быть совершено несколько действий. Количество и последовательность действий зависят от типа операции. Список типов операций см. в документации History&Notifications API.

Клиент может совершить отмену (например, отменить заказ на покупку товара). В этом случае платёжная система, которая обслуживает карту, отправит QIWI запрос на отмену операции. QIWI (BaaS) совершит необходимое действие, создаст запись о его выполнении для уже существующей операции и уведомит об этом партнёра, если такая возможность настроена.

Пример записи в BaaS о получении запроса на отмену покупки в интернете приведён ниже. В примере запрос получен по операции покупки c идентификатором txn1, в рамках которой BaaS ранее зарезервировал денежные средства на карте клиента.

Пример

txnId txnType actionId actionType actionStatus
txn1 PURCHASE_E_POS act1 HOLD SUCCESS
txn1 PURCHASE_E_POS act2 REVERSAL SUCCESS

Описание полей см. в документации History&Notifications API.

Пример успешной покупки и отмены покупки в интернет-магазине с помощью карты QIWI изображён на диаграмме ниже.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":15,
        "noteFontSize":13,
        "actorMargin":
        75 }}}%%
sequenceDiagram
    participant С as Клиент
    participant I as Интернет-магазин
    participant PS as Платёжная система
    participant B as BaaS
    С->>I: Покупка товара
    Note right of С: «Оплатить»
    I->>PS: Запрос на авторизацию покупки txn1
    Note right of I: Через систему банка-эквайера
    PS->>B: Запрос на авторизацию покупки txn1
    B->>B: HOLD
    B->>PS: 200 OK
    PS->>I: 200 OK
    Note left of PS: Через систему банка-эквайера
    I->>С: Коммуникация с клиентом
    Note right of С: Заказ подтверждён, средства зарезервированы на карте
    С->>I: Отмена заказа
    Note right of С: «Отменить»
    I->>PS: Запрос на авторизацию отмены покупки txn1
    Note right of I: Через систему банка-эквайера
    PS->>B: Запрос на авторизацию отмены покупки txn1
    B->>B: REVERSAL
    B->>PS: 200 OK
    PS->>I: 200 OK
    Note left of PS: Через систему банка-эквайера
    I->>С: Коммуникация с клиентом
    Note right of С: Заказ отменён, средства доступны для использования

Список возможных действий и их описание см. в документации History&Notifications API.

Офлайн-операция

Платёжная система, которая обслуживает карту, отправляет QIWI клиринговый файл. В этом файле содержатся записи об операциях, совершённых на стороне платёжной системы.

Обратите внимание

Клиринговый файл может содержать как запись по операции, для которой BaaS уже получал запрос на авторизацию (авторизационный клиринг), так и запись по операции, для которой запрос на авторизацию не приходил (безавторизационный клиринг).

Для каждой записи из клирингового файла BaaS выполняет определённое действие (например, списывает денежные средства с карты клиента) и уведомляет об этом партнёра, если такая возможность настроена.

Пример записи в BaaS о получении авторизационного клиринга приведён ниже. В примере клиринг получен по операции совершения покупки в интернете c идентификатором txn1, а BaaS ранее зарезервировал средства для этой покупки в рамках получения запроса на авторизацию.

Пример

txnId txnType actionId actionType actionStatus
txn1 PURCHASE_E_POS act1 HOLD SUCCESS
txn1 PURCHASE_E_POS act2 CAPTURE_HOLD SUCCESS

Описание полей см. в документации History&Notifications API.

Пример записи в BaaS о получении безавторизационного клиринга по операции совершения покупки в интернете будет содержать лишь одну строку с actionType:CAPTURE_HOLD.

Пример успешной покупки в интернет-магазине с помощью карты QIWI изображён на диаграмме ниже.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":15,
        "noteFontSize":13,
        "actorMargin":
        75 }}}%%
sequenceDiagram
    participant С as Клиент
    participant I as Интернет-магазин
    participant PS as Платёжная система
    participant B as BaaS
    С->>I: Покупка товара
    Note right of С: «Оплатить»
    I->>PS: Запрос на авторизацию покупки txn1
    Note right of I: Через систему банка-эквайера
    PS->>B: Запрос на авторизацию покупки txn1
    B->>B: HOLD
    B->>PS: 200 OK
    PS->>I: 200 OK
    Note left of PS: Через систему банка-эквайера
    I->>С: Коммуникация с клиентом
    Note right of С: Заказ подтверждён
    PS->>B: Клиринговый файл с записью о покупке txn1
    B->>B: CAPTURE_HOLD

Список возможных действий и их описание см. в документации History&Notifications API.

Обратите внимание

Запись о возврате покупки (REFUND) в файле клиринга не будет иметь ссылки на саму покупку, так как REFUND является отдельной операцией зачисления денежных средств со счёта провайдера услуг на счёт клиента.

В рамках одной покупки может поступить несколько отдельных записей в одном или разных файлах клиринга. Записи могут содержать разные суммы. Такой случай в терминологии BaaS называется мультиклирингом.

Пример мультиклиринга

  1. Клиент совершил покупку двух авиабилетов в рамках одного бронирования на общую сумму 20 000 руб.
  2. BaaS авторизовал покупку с идентификатором txn1 на сумму 20 000 руб., захолдировал денежные средства на счёте клиента и отправил партнёру уведомление.
  3. Платёжная система отправила QIWI файл клиринга на следующий день после авторизации покупки. В файле была запись о совершении покупки txn1 на сумму 10 000 руб и признак multiClearingData, говорящий о том что расчёты по операции txn1 ещё не закончены.
  4. QIWI (BaaS) списал 10 000 руб. со счёта клиента и отправил партнёру уведомление.
  5. Платёжная система отправила QIWI ещё один файл клиринга на следующий день после отправки файла из п.3. В файле была запись о совершении покупки txn1 на сумму 10 000 руб. и отсутствовал признак multiClearingData.
  6. QIWI (BaaS) списал 10 000 руб. со счёта клиента и отправил партнёру уведомление.

Статусная модель

Жизненный цикл действия, которое приводит к движению средств, изображён на диаграмме ниже.

flowchart TD
    Start --> SUCCESS
    Start --> FAILED
Платёжная система отправляет запрос на авторизацию операции или клиринговый файл. BaaS выполняет движение денежных средств и создаёт запись об этом движении с одним из следующих статусов:

  • SUCCESS — когда действие выполнено успешно;
  • FAILED — когда действие не выполнено (в этом случае BaaS зафиксирует одну из перечисленных в документации History&Notifications API ошибок авторизации).