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

Перевод на банковскую карту

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

Клиент может перевести деньги:

Перевод из авторизованной зоны

Описание авторизованной зоны см. в статье «Термины и бизнес-сущности».

Перевод из такой зоны является операцией домена PAYMENTS. Партнёр может реализовать его несколькими способами:

  • c помощью API;
  • с помощью формы.

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

Не имеет значения, выпущена для клиента банковская карта в платформе или нет — деньги будут списаны с его счёта.

Перевод c помощью API

Для перевода средств на банковскую карту c помощью API партнёру необходимо:

Пример успешного сценария перевода средств на банковскую карту c помощью API описан и изображён ниже.

  1. Клиент нажимает «Перевести» в интерфейсе партнёра.
  2. Партнёр отображает клиенту форму для ввода платёжных данных.
  3. Клиент вводит сумму перевода и номер банковской карты (PAN).

    Опциональные шаги

    П.4 является опциональным и выполняется лишь в том случае, если бизнес-сценарием предусмотрена комиссия с клиента за совершение перевода.

  4. Партнёр выполняет сценарий «Получение комиссии».

  5. Партнёр отправляет BaaS запрос на перевод средств.
  6. BaaS возвращает партнёру статус проведения платежа «В процессе проведения» (status:PROCESSING) и информацию о необходимости подтвердить перевод (needClientApprove).

    Опциональные шаги

    П.7 - п.9 являются опциональными и выполняются лишь в том случае, если needClientApprove имеет значение true.

  7. Партнёр информирует клиента о том, что перевод на указанную карту является потенциально подозрительной операцией: получатель денежных средств, возможно, относится к числу финансовых мошенников.

  8. Клиент подтверждает выполнение перевода.
  9. Партнёр отправляет BaaS запрос на подтверждение.
  10. BaaS переводит средства со счёта клиента на банковскую карту.
  11. Партнёр принимает решение об успешности проведения платежа — выполняет действия, указанные в статье «Общие принципы и правила» → «Решение об успешности платежа» → «Асинхронный вариант проведения платежа».
%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":15,
        "noteFontSize":13,
        "actorMargin":
        75 }}}%%
sequenceDiagram
    participant С as Клиент
    participant P as Партнёр
    participant B as BaaS
    С->>P: Перевод на карту в интерфейсе
    Note right of С: «Перевести»
    P->>С: Форма для перевода
    С->>P: Ввод данных
    Note right of С: Сумма перевода, номер карты
    opt Сценарий «Получение комиссии» (опционально)
    P->>+B: 
    B->>-P: 
    Note left of B: clientCommission
    P->>+С: 
    С->>P: 
    Note left of P: clientCommission
    end
    P->>+B: Запрос на перевод
    Note over P, B: productId, transactionId, fromAccountId, pan, transactionAmount, clientCommission
    B->>-P: Ответ на запрос перевода
    Note over P, B: status:PROCESSING, needClientApprove
    opt Получение подтверждения (опционально)
    P->>С: Коммуникация с клиентом
    Note left of P: Подозрительная операция
    С->>P: Подтверждение перевода
    P->>+B: Запрос на подтверждение
    Note over P, B: productId, transactionId, currency, clientApproveStatus:APPROVED
    B->>-P: Ответ на запрос подтверждения
    Note over P, B: clientApproveStatus:APPROVED
    end
    rect rgb(255, 238, 223)
    P->>+B: Сценарий «Решение об успешности платежа»
    B-->>-P: 
    Note left of B: status:SUCCESS
    end
    P->>С: Коммуникация с клиентом

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

Жизненный цикл операции перевода описан в этой статье.

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

Действия, указанные в статье «Общие принципы и правила» → «Решение об успешности платежа» → «Асинхронный вариант проведения платежа», являются обязательными для выполнения.

Важная информация

При реализации сценария необходимо учитывать существующие правила и ограничения.

Перевод c помощью формы

Форма позволяет клиенту совершить перевод по номеру карты. Является альтернативой использованию Payments API. Преимущество использования формы в том, что партнёру не требуется:

Использование формы

Партнёру необходимо добавить JavaScript-код на экран или страницу интерфейса, предназначенную для перевода средств на банковскую карту.

Пример JavaScript-кода

  <script src="https://openapi-widget.qiwi.com/script.js" type="text/javascript"></script>
  <script>
    const widget = window.qwl.createPayTransferWidget({
      formUrl: 'https://openapi-widget.qiwi.com',
      token: '4ee7***ce61',
      allowCopy: 'clipboard-read; clipboard-write self',
      signature: '6cff***f555',
      style: {
        isModal: false,
        btn: ':hover {
          background: green;
        }',
        input: 'border-radius: 10px;
            :hover {
              color: red;
            }',
        layout: 'background: tomato;',
        rootId: 'form-container',
        titleColor: '#3c3c5b',
        errorColor: ''
      },
      callback: data => alert(JSON.stringify(data))
    })
    widget.mount()
  </script>

Важная информация

Партнёру необходимо передать BaaS список доменов, на которых будет расположен экран или страница с JavaScript-кодом. В ином случае совершить перевод с помощью формы не удастся.

Описание параметров и переменных

Наименование Описание
formUrl Значение параметра formUrl из ответа на запрос получения токена формы
token Значение параметра formToken из ответа на запрос получения токена формы
signature Значение, вычисляемое по алгоритму HmacSHA256 на основе “секрета” и formToken (алгоритм вычисления см. в статье «Общие принципы и правила»«Вычисление цифровой подписи»)
style Переменная, отвечающая за кастомизацию формы. Подробнее в разделе «Кастомизация»
callback Callback-функция. Подробнее в разделе «Callback»

Получение, вычисление и подстановка значений для formUrl, token, signature в код выполняются при каждой попытке клиента совершить перевод по номеру карты.

Успешный сценарий перевода на банковскую карту c помощью формы изображён на диаграмме ниже.

%%{init: {
    "sequence" : {
        "wrap":true,
        "messageFontSize":13,
        "noteFontSize":12,
        "width":140,
        "actorMargin":90}}}%%
sequenceDiagram
    participant С as Клиент
    participant PF as Партнёр (Frontend)
    participant PB as Партнёр (Backend)
    participant B as BaaS
    С->>PF: Переход на страницу интерфейса
    Note over С, PF: Страница для перевода по номеру карты
    PF->>+PB: Запрос на получение токена формы
    Note right of PF: clientData
    PB->>+B: Запрос на получение токена формы
    Note right of PB: productId, fromAccountId, transactionId
    B-->>-PB: Ответ на запрос получения токена формы
    Note left of B: formToken, formUrl
    PB->>PB: Вычисление signature
    PB-->>-PF: Ответ на запрос получения токена формы
    Note left of PB: formToken, formUrl, signature
    PF->>PF: Встраивание значений в JS-код
    rect rgb(230, 230, 230)
    Note over PF, B: JS-код формы перевода на банковскую карту
    С->>PF: Ввод платёжных данных
    Note over С, PF: Номер карты получателя и сумма перевода
    PF->>+B: Выполнение JS-кода (вызов API)
    B-->>-PF: clientCommission
    PF->>С: Отображение данных на форме в интерфейсе
    Note left of PF: Комиссия
    С->>PF: Подтверждение перевода
    Note over С, PF: «Перевести»
    PF->>+B: Выполнение JS-кода (вызов API)
    B-->>-PF: Результат обработки запроса (объект JSON)
    Note right of PB: status:PROCESSING
    PF->>PF: Вызов callback-функции
    end
    PF->>С: Коммуникация с клиентом
    Note left of PF: Перевод выполняется
    rect rgb(255, 238, 223)
    PF->>+B: Сценарий «Решение об успешности платежа»
    B->>-PF: 
    Note left of PB: status:SUCCESS
    end
    PF->>С: Коммуникация с клиентом
    Note left of PF: Перевод успешен

Запросы описаны в документации Payments API. Сценарий принятия решения об успешности платежа см. в статье «Общие принципы и правила» → «Решение об успешности платежа» → «Асинхронный вариант проведения платежа».

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

  • Партнёр не получает, не обрабатывает и не хранит данные карты получателя, а также не вычисляет комиссию за совершение перевода. Это делает форма. Данный этап выделен на схеме серым цветом.
  • Партнёру необходимо самостоятельно реализовать отображение результата проведения платежа. Подробнее в разделе «Callback».
  • Действия, указанные в статье «Общие принципы и правила» → «Решение об успешности платежа» → «Асинхронный вариант проведения платежа».

Важная информация

При реализации сценария необходимо учитывать существующие правила и ограничения.

Кастомизация формы

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

Пример style

      style: {
        isModal: false,
        btn: ': hover {
          background: gray;
        }',
        input: 'border-radius: 10px;
            :hover {
              color: orange;
            }',
        layout: 'background: orange;',
        rootId: 'form-container',
        titleColor: gray,
        errorColor: 'orange'
      }

Описание параметров

Наименование Описание
isModal Признак, говорящий о том, является ли форма модальным окном (true/false)
btn CSS-стиль кнопки для перевода. Можно задать стиль кнопки при наведении на неё мышкой с помощью :hover {YOUR_STYLE}
input CSS-стиль полей с платёжными данными. Можно задать стиль полей при наведении на них мышкой с помощью :hover {YOUR_STYLE}
layout CSS-стиль подложки (фона). Можно задать стиль фона при наведении на него мышкой с помощью :hover {YOUR_STYLE}
rootId Идентификатор контейнера, в который будет встраиваться форма
titleColor Цвет заголовка и кнопки закрытия формы. Указывается, если выбрано модальное отображение (isModal: true). Может иметь вид red, #3c3c3c и др. согласно стандарту CSS
errorColor Цвет текста ошибки в случае некорректного заполнения полей ввода данных. Может иметь вид red, #3c3c3c и др. согласно стандарту CSS

Пример формы

LINKS

Callback

Callback — это функция, которая вызывается после того, как клиент нажал на кнопку «Перевести» и платформа вернула результат обработки запроса на перевод (см. раздел «Использование формы»).

Пример

data => alert(JSON.stringify(data))

Здесь результат выводится с помощью метода alert(). Партнёр может использовать собственное решение.

Callback-функции передаётся единственный аргумент (data) в виде объекта JSON с полем:

  • result — в случае успешной обработки платёжного запроса;
  • error — в случае ошибки при обработке платёжного запроса.

Формат data аналогичен формату ответа Payments API на запрос перевода средств.

Объект JSON в случае успешной обработки запроса

{
  "result": {
    "productId": "fake-product",
    "transactionId": "96d6***ca6ec",
    "fromAccountId": "34f2***058fa",
    "transactionAmount": {
      "currency": "RUB",
      "value": "12333.00"
    },
    "clientCommission": {
      "currency": "RUB",
      "value": "246.66"
    },
    "creationDateTime": "2022-06-20T17:31:57.688546+03:00",
    "accountingDateTime": "2022-06-20T17:31:57.688553+03:00",
    "status": "PROCESSING",
    "statusDetails": {},
    "needClientApprove": false
  }
}

Описание см. в документации Payments API: Перевод на банковскую картуОтвет.

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

Наличие result не говорит об успешности самого перевода, статус перевода находится в result.status.

Объект JSON в случае ошибки

{
  "error": {
    "dateTime": "2022-06-28T10:56:08.584631+03:00",
    "description": "Undefined error. Please try to make operation later.",
    "errorCode": "openapi.payment.api.withdrawal.to.card.token.expired",
    "serviceName": "openapi-payment-api",
    "traceId": "6d1c4afcf941a949",
    "userMessage": "Undefined error. Please try to make operation later."
  }
}

Формат error аналогичен формату ошибок Payments API. Справочник кодов ошибок представлен в таблице ниже.

Код Описание
openapi.frontend.api.client.blocked Клиент заблокирован
openapi.frontend.api.precheck.failed Запрос не прошел банковские проверки, такие как превышение лимита. Финансовая операция не создана
openapi.frontend.api.invalid.txn.amount Неверная сумма платежа
openapi.frontend.api.txn.parameter.changed Платеж с таким идентификатором транзакции уже создан и его параметры отличаются от переданных в запросе
openapi.frontend.api.unauthorized Ошибка авторизации: подпись неверна, токен устарел и др.

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

Партнёру необходимо самостоятельно реализовать отображение результата проведения платежа. При обработке data мы рекомендуем проверить:

  • наличие error, чтобы показать клиенту сообщение об ошибке;
  • значение result.status, чтобы основываясь на нём выстроить правильную коммуникацию с клиентом.

Демонстрационная страница

BaaS может открыть партнёру доступ к демо-странице, для этого следует обратиться к курирующему менеджеру.

После открытия страницы перейдите на вкладку Pay transfer widget. Примерный вид страницы — на изображении ниже.

LINKS

Демо-страница позволяет:

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

Чтобы увидеть результат кастомизации, необходимо:

  • настроить стили согласно примеру на изображении выше;
  • применить стили, нажав на соответствующую кнопку.

Чтобы протестировать работу формы, необходимо:

  • ввести значения formUrl, token, signature, style (как получить значения см. в разделе «Использование формы»);
  • применить настройки, нажав на соответствующую кнопку;
  • ввести номер карты получателя и сумму перевода.
  • нажать «Перевести» на форме.

Для отображения результата на демо-странице callback-функция определена так, чтобы ответ появился в модальном окне. Партнёр на своей странице может использовать собственное решение.

LINKS

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

Для formUrl, token, signature на демо-странице допускается использовать лишь значения, полученные из тестовой среды. Для их получения партнёру следует отправлять запросы на тестовый URL.

Тестирование

Общие правила тестирования описаны в статье BaaS → «Тестирование». Здесь мы расскажем об особенностях тестирования сценариев перевода средств на банковскую карту из авторизованной зоны.

Тестовые данные

В запросе на перевод или на форме используйте следующий номер карты: 4874154455550061.

Особенности

В тестовой среде отсутствует этап подтверждения перевода — needClientApprove всегда имеет значение false.

Перевод из неавторизованной зоны

Описание неавторизованной зоны см. в статье «Термины и бизнес-сущности».

Перевод из такой зоны является операцией домена CARDS и выполняется по сценарию, описанному ниже.

  1. Клиент:

    • заходит на сайт или в мобильное приложение интернет-банка;
    • выбирает перевод по номеру карты;
    • указывает данные карты QIWI в качестве отправителя;
    • указывает номер карты другого банка в качестве получателя;
    • вводит сумму и нажимает «Перевести».
  2. Интернет-банк с помощью платёжной системы, которая обслуживает карту, проводит платёж.

Партнёр узнаёт о факте совершения перевода, получив уведомление, подробности см. в статье «Уведомление»«Уведомление об операциях домена CARDS».