Подключение оплаты по платежной ссылке

Инструкция описывает сценарий оплаты по платёжной ссылке на Android через модуль pay-with-redirect модульного мобильного SDK. Общая концепция модулей — в разделе Модульный мобильный SDK.

Общая информация

Схема работы

  1. Пользователь нажимает на кнопку оплаты в приложении.
  2. Пользователь переходит на экран платежной формы Яндекс Пэй, где отображается информация о заказе и способы оплаты:

    • список банковских карт пользователя;
    • варианты оплаты через систему быстрых платежей (СБП).
  3. Пользователь выбирает способ оплаты и нажимает на кнопку подтверждения заказа.

  4. Сервис Яндекс Пэй проводит платеж и возвращает результат выполнения операции.

Полная оплата

flow

Оплата в сплит

flow

Требования к подключению

Поддерживаемая версия: Android 7.0 (API 24) и выше. Для сборки рекомендуется Java 17 и Kotlin 2.x.

Если ваш проект имеет minSdkVersion ниже 24, см. раздел «Устройства с версией Android ниже 7.0».

Шаг 1. Подготовка идентификаторов

Перед началом интеграции получите идентификаторы, которые понадобятся при подключении SDK:

1.1 Получение SHA256 Fingerprints

Получите значение хеша SHA256 Fingerprints с помощью утилиты keytool:

keytool -list -v -alias <your-key-name> -keystore <path-to-production-keystore>

После ввода команды значение хеша отобразится в блоке Certificate fingerprints: SHA256.

1.2 Получение Client ID

Чтобы получить Client ID, зарегистрируйте приложение в сервисе Яндекс OAuth — это нужно, чтобы покупатели при оплате через Яндекс Пэй могли авторизоваться с помощью своего Яндекс ID.

Важно

Аккаунт, с которого вы регистрируете приложение в Яндекс OAuth, должен в Яндекс ID состоять в организации и иметь права разработчика. Добавить аккаунт в организацию и выдать права может сотрудник с ролью Владелец или Администратор.

Как проверить наличие прав
  • Если аккаунт состоит организации, в Яндекс OAuth при нажатии на фото профиля отображается название организации:

  • Чтобы проверить наличие прав разработчика, в Яндекс ID перейдите в список сотрудников организации → профиль сотрудника → Права в сервисах → Яндекс ID для сайта:

  1. Перейдите в сервис Яндекс OAuth, нажмите кнопку Создать, выберите вариант Для авторизации пользователей и перейдите к созданию.

  2. В поле Название вашего сервиса укажите название, которое будет отображаться пользователям на экране авторизации, и загрузите иконку приложения.

  3. В разделе Платформы приложений выберите Android-приложение и укажите его параметры:

    • Android package name — уникальное имя приложения из applicationId в конфигурационном файле проекта;
    • SHA256 Fingerprints — значение хеша SHA256. Все буквы в хеше должны быть заглавными.

  4. Добавьте доступ к Яндекс Пэй: в разделе Права доступа к данным пользователей в поле Название доступа укажите и выберите Оплата через Yandex Pay.

    Примечание

    Доступ Управление заказами Yandex Pay Checkout не требуется. Если он у вас добавлен, удалите его.

  5. Нажмите кнопку ПродолжитьВсё верно, создать приложение и скопируйте значение поля Client ID.

  6. В разделе Настройки личного кабинета Яндекс Пэй нажмите Добавить Client ID и укажите значение Client ID.

    Там же в разделе Настройки нажмите Добавить приложения, выберите нужный Client ID, платформу приложения и укажите SHA256 и Android package name в полях SHA256 Fingerprint и Android package name соответственно.

Шаг 2. Настройка проекта

Подготовьте Android-проект к работе с Яндекс Пэй SDK: подключите полученный Client ID и инициализируйте Firebase и AppMetrica.

2.1 Подключение Client ID

Укажите полученный Client ID в сборочном скрипте build.gradle в manifestPlaceholders в качестве значения YANDEX_CLIENT_ID:

android {
  defaultConfig {
    manifestPlaceholders = [
      // Подставьте ваш Client ID
      YANDEX_CLIENT_ID: "12345678901234567890",
    ]
  }
}

2.2 Инициализация FirebaseApp

Мобильный SDK использует службы AppMetrica, которые необходимы для стабильной работы SDK. Этот шаг позволяет исправить проблемы совместимости сервисов Firebase и сервисов метрик.

При использовании Firebase вместе с Яндекс Пэй SDK необходимо вызывать FirebaseApp.initialize(context) во всех процессах приложения.

Если вы используете AppMetrica в своем приложении, активировать YandexMetrica необходимо после инициализации Firebase.

Пример
// Не забудьте объявить MyApplication в AndroidManifest.xml в блоке <application/>, используя android:name
class MyApplication: Application() {

    override fun onCreate() {
        // Инициализируется в каждом процессе приложения
        FirebaseApp.initializeApp(this)
    }
}

Шаг 3. Подключение модуля pay-with-redirect

Укажите зависимость в сборочных скриптах (пример для Kotlin DSL). Версию выставьте так же, как для остальных артефактов com.yandex.pay в проекте — например 2.9.0:

dependencies {
    implementation("com.yandex.pay:pay-with-redirect:2.9.0")
}

Шаг 4. Инициализация SDK

Вызовите YPay.init один раз при старте приложения (например, в Application.onCreate). В список flows обязательно передайте payWithRedirectFlow(merchantId = …).

Общие параметры среды и оформления задаются в лямбде инициализации:

Параметр Тип По умолчанию Описание
environment YPayEnvironment PRODUCTION PRODUCTION или SANDBOX
theme YPayTheme SYSTEM SYSTEM, LIGHT, DARK
locale YPayLocale SYSTEM SYSTEM, RU, EN
import com.yandex.pay.facade.api.YPay
import com.yandex.pay.withredirect.api.facade.payWithRedirectFlow
import com.yandex.pay.configuration.YPayEnvironment
import com.yandex.pay.configuration.YPayLocale
import com.yandex.pay.configuration.YPayTheme

YPay.init(
    context = this,
    flows = listOf(
        payWithRedirectFlow(merchantId = "your-merchant-id"),
    ),
) {
    environment = YPayEnvironment.PRODUCTION
    theme = YPayTheme.SYSTEM
    locale = YPayLocale.SYSTEM
}

Без регистрации этого флоу обращение к YPay.payWithRedirect приведёт к ошибке; для проверки наличия модуля на classpath можно использовать YPay.payWithRedirectOrNull.

Если в приложении уже вызывается YPay.init с другими флоу (например, виджет выгод или in-app), добавьте payWithRedirectFlow в тот же список flows, не вызывая YPay.init повторно.

Шаг 5. Получение объекта платежной сессии

Сессия создаётся через YPay.payWithRedirect и используется и для кнопки оплаты, и для лаунчера.

import com.yandex.pay.facade.api.YPay
import com.yandex.pay.withredirect.api.session.PaymentSessionKey

// Сессия со случайным ключом по умолчанию
val paymentSession = YPay.payWithRedirect.getYandexPaymentSession()

// Явный ключ — например, для нескольких параллельных чекаутов
val sessionKey = PaymentSessionKey(value = "checkout-screen-session")
val checkoutSession = YPay.payWithRedirect.getYandexPaymentSession(sessionKey = sessionKey)

Конфигурация мерчанта для редирект-флоу задаётся при payWithRedirectFlow, отдельный YPayConfig для этой сессии не передаётся.

Освободите сессию при уничтожении экрана (или когда сессия больше не нужна):

override fun onDestroy() {
    super.onDestroy()
    YPay.payWithRedirect.removePaymentSession(sessionKey = paymentSession.sessionKey)
}

Шаг 6. (опционально) Размещение кнопки Яндекс Пэй на экране

Нативная кнопка com.yandex.pay.withredirect.api.button.YPayButton, атрибуты XML, персонализация и bindTo / setOnClickListener описаны в разделе Кнопки оплаты Яндекс Пэй.

Кратко: в разметке объявите YPayButton, затем вызовите bindTo(paymentSession, SessionListenerArgs(…)) и зарегистрируйте setOnClickListener(yPayLauncher, …) — см. шаг 9.

Шаг 7. Инициализация лаунчера

YPayLauncher регистрирует контракт ActivityResult. Создавайте его в Activity или Fragment до onStart (например, в конструкторе поля класса).

Передайте YPayLauncherCallback для получения YPayResult:

import com.yandex.pay.withredirect.api.launcher.YPayLauncher
import com.yandex.pay.withredirect.api.launcher.YPayLauncherCallback
import com.yandex.pay.payment.YPayResult

private val yandexPayLauncher = YPayLauncher(
    activityResultCaller = this,
    paymentProcessCallback = YPayLauncherCallback { result ->
        when (result) {
            is YPayResult.Success -> { /* см. шаг 10 */ }
            is YPayResult.Cancelled -> { }
            is YPayResult.Failure -> { /* result.errorMsg, result.metadata */ }
        }
    },
)

Шаг 8. Формирование данных для запуска Яндекс Пэй

Платёжная ссылка приходит с вашего бэкенда (Pay API). Соберите PaymentData и YPayContractParams:

import com.yandex.pay.payment.PaymentData
import com.yandex.pay.payment.Metadata
import com.yandex.pay.withredirect.api.launcher.YPayContractParams

val paymentData = PaymentData(
    paymentUrl = "https://pay.yandex.ru/...", // URL заказа из Pay API
    metadata = Metadata(value = "opaque-id"), // опционально; вернётся в результате
)

val params = YPayContractParams(
    paymentSession = paymentSession,
    paymentData = paymentData,
)

Примечание

Если вы хотите проводить оплату в Сплит, при создании ссылки передайте необходимые параметры в availablePaymentMethods.

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

Шаг 9. Запуск сервиса Яндекс Пэй

Запуск через кнопку Яндекс Пэй

Передайте YPayLauncher в YPayButton.setOnClickListener. В колбэке получите YPayButtonLauncher и вызовите launch(YPayContractParams). Данные оплаты можно подготовить заранее или в течение 10 секунд после нажатия; иначе пользователь получит ошибку (см. коды ошибок).

yPayButton.setOnClickListener(yandexPayLauncher) { buttonLauncher ->
    val params = YPayContractParams(
        paymentSession = paymentSession,
        paymentData = PaymentData(paymentUrl = getPaymentUrl()),
    )
    buttonLauncher.launch(params)
}

Важно

У YPayButton переопределён setOnClickListener: используйте только перегрузку с YPayActionLauncher и YPayButton.OnClickListener. Вызов View.setOnClickListener приведёт к исключению.

Сначала вызовите bindTo на кнопке, иначе обработчик нажатия не сработает — см. Работа с кнопкой.

Запуск без кнопки

yandexPayLauncher.launch(params)

Шаг 10. Обработка результата

После запуска Яндекс Пэй SDK выберет оптимальную стратегию редиректа и откроет платёжную форму. Итог приходит в YPayLauncherCallback.

fun handlePaymentResult(result: YPayResult) {
    when (result) {
        is YPayResult.Success -> {
            val orderId = result.orderId.value
            val metadata = result.metadata?.value
        }
        is YPayResult.Failure -> {
            val message = result.errorMsg
            val metadata = result.metadata?.value
        }
        YPayResult.Cancelled -> { }
    }
}

Коды ошибок YPayResult.Failure

Код (errorMsg) Описание
incorrect payment url Неверная платёжная ссылка
transaction error Ошибка проведения транзакции
failed to parse order ID Не удалось получить orderId
invalid intent parsing Не удалось разобрать результат оплаты из Intent
invalid result code Неверный код результата Activity
unresolved payment strategy Приложение было закрыто в фоне во время оплаты
session key not provided Не передан ключ сессии
payment data not provided Не передан объект PaymentData
Timeout. YPayContractParams was not provided Для сценария с кнопкой параметры запуска не были переданы в течение 10 секунд после нажатия

Примечание

Примечание

При возникновении трудностей с настройкой посмотрите пример интеграции.

Состояние и обновление SDK

API Назначение
YPay.isInitialized Признак завершённой инициализации
YPay.configuration Текущая YPayConfiguration (тема, локаль, среда) или null
YPay.updateConfiguration { … } Смена темы и локали после init
YPay.payWithRedirect.reinit(merchantId = …) Смена мерчанта без полного сброса SDK; после вызова создайте сессию заново
YPay.clear() Сброс состояния флоу и фасада (например, при выходе пользователя); затем можно снова вызвать YPay.init

Динамически сменить тему оформления кнопки на экране можно через свойство colorScheme у YPayButton — см. Параметры кнопки.

Настройка для устройств с версией ниже 7.0

Артефакт pay-with-redirect объявляет minSdkVersion 24. Для пользователей с Android 7.0+ дополнительных действий не требуется.

Если приложению нужно собирать проект с minSdkVersion ниже 24, потребуется обход конфликта слияния манифестов (поддержка на стороне приложения не гарантируется):

  1. Подключите зависимость com.yandex.pay:pay-with-redirect (см. шаг 3).

  2. Синхронизируйте проект. Ожидаемая ошибка слияния:

    Manifest merger failed : uses-sdk:minSdkVersion *Your min version* cannot be smaller than version 24 declared in library
    
  3. В AndroidManifest.xml модуля с зависимостью добавьте переопределение для библиотек из сообщения об ошибке (перечислите фактические пакеты из лога сборки):

    <manifest xmlns:tools="http://schemas.android.com/tools">
        <uses-sdk tools:overrideLibrary="com.yandex.pay.withredirect,…"/>
    </manifest>
    
  4. На устройствах с API ниже 24 не вызывайте API модуля или заранее проверяйте версию системы (например, Build.VERSION.SDK_INT >= Build.VERSION_CODES.N), чтобы не обращаться к SDK на неподдерживаемых версиях ОС.

Предыдущая
Следующая