Миграция на Yandex Pay Kit

Это руководство поможет перейти с монолитного YandexPaySDK версии 1.x на новый модульный SDK Yandex Pay Kit (SDK 2.x). Модули Yandex Pay Kit независимы друг от друга — вы можете подключить только то, что нужно вашему приложению.

Что изменилось

Параметр

iOS SDK 1.x
(было)

iOS SDK 2.x
Yandex Pay Kit
(стало)

Системные требования

Версия iOS

14.0 и выше

15.0 и выше

Версия Swift

6.0 и выше

6.0 и выше

Версия Xcode

16.4 и выше

Ключевые элементы

Главный класс

YandexPaySDKApi

YPay

Тип мерчанта

YandexPaySDKMerchant

YPSDKMerchant

Тип окружения

YandexPaySDKEnvironment

YPSDKEnvironment

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

YandexPaySDKApi.initialize(configuration:)

YPay.initialize(environment:locale:modules:)

Синглтон

YandexPaySDKApi.instance

YPay.instance

Форма оплаты

YandexPaySDKApi.instance.createYandexPayForm(...)

YPay.instance.payWithRedirect.createYandexPayForm(...)

Кнопка оплаты

YandexPaySDKApi.instance.createButton(...)

YPay.instance.payWithRedirect.createButton(...)

Бейджи

YandexPaySDKApi.instance.createBadgeView(...)

YPay.instance.inventory.createBadgeView(...)

Обработка диплинков

applicationDidReceiveOpen / applicationDidReceiveUserActivity

deeplinkHandler.handleOpenURL / handleUserActivity

Шаг 1. Обновление версии пакета

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

Примечание

Актуальная версия Yandex Pay Kit для iOS — 2.1.1.

Было:

.package(
   url: "https://github.com/yandexmobile/yandex-pay-ios.git",
   from: "1.0.0"
)
Стало:

.package(
   url: "https://github.com/yandexmobile/yandex-pay-ios.git",
   from: "2.1.1" // укажите здесь актуальную версию
)

Добавьте в цель только нужные модули:

.target(
   name: "MyApp",
   dependencies: [
      .product(name: "YandexPayWithRedirect", package: "yandex-pay-ios"),
      .product(name: "YandexPayInventory",    package: "yandex-pay-ios"),
      // другие модули при необходимости
   ]
)

YandexPayConfiguration подключается как транзитивная зависимость через любой модуль — явно добавлять его не нужно.

Было:

Подключается SDK целиком.

pod 'YandexPaySDK'
Стало:

Подключаются только нужные модули.

pod 'YandexPaySDK/YandexPayWithRedirect'  # кнопка и форма оплаты
pod 'YandexPaySDK/YandexPayInventory'     # бейджи
# другие при необходимости

Доступные модули

Модуль Зависимость Описание
CP QR YandexQuickPay Customer Presented QR. Быстрая оплата через QR-код в офлайн-точках.
Ассистент YandexPayAssistant Виджеты выгод и сценарии ИИ-ассистента от Яндекс Пэй.
Авторизация YandexPayAuth Авторизация пользователя в Яндекс Пэй и передача состояния авторизации партнера.
Редирект YandexPayWithRedirect PSP-оплата через платежную ссылку с редиректом в платежную форму.
Пэй Виджет YandexPayInApp Виджет быстрой онлайн-оплаты на checkout-странице. Подключается вместе с модулем «Редирект» (YandexPayWithRedirect).
Инвентарь YandexPayInventory Бейджи Яндекс Пэй с информацией о скидках, кешбэке баллами Плюса или платежах Яндекс Сплит.

Шаг 2. Обновление импортов

Замените единственный импорт на точечные импорты нужных модулей.

Было:

import YandexPaySDK
Стало:

import YandexPayConfiguration  // базовые типы, YPay
import YandexPayWithRedirect    // кнопка и форма оплаты
import YandexPayInventory       // бейджи

Шаг 3. Обновление инициализации

Конфигурация переработана:

  • параметры передаются напрямую в YPay.initialize вместо YandexPaySDKConfiguration;
  • возможности подключаются через массив модулей.
Было:

import YandexPaySDK

let merchant = YandexPaySDKMerchant(
   id: "MERCHANT_ID",
   name: "MERCHANT_NAME",
   url: "https://example.org/"
)
let configuration = YandexPaySDKConfiguration(
   environment: .sandbox,
   merchant: merchant,
   locale: .ru
)
YandexPaySDKApi.initialize(configuration: configuration)
Стало:

import YandexPayConfiguration  // ← изменено
import YandexPayWithRedirect    // ← добавлено
import YandexPayInventory       // ← добавлено

let merchant = YPSDKMerchant(  // ← изменено
   id: "MERCHANT_ID",
   name: "MERCHANT_NAME",
   url: "https://example.org/"
)

YPay.initialize(  // ← изменено
   environment: .sandbox,
   locale: .ru,
   modules: [  // ← добавлено
      YPayWithRedirect.module(merchant: merchant),
      YPayInventory.module(merchant: merchant),
   ]
)
Было:

import YandexPaySDK

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
      guard YandexPaySDKApi.isInitialized else { return false }
      return YandexPaySDKApi.instance.applicationDidReceiveOpen(url, options: options)
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity,
                  restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
      guard YandexPaySDKApi.isInitialized else { return false }
      return YandexPaySDKApi.instance.applicationDidReceiveUserActivity(userActivity)
}
import YandexPaySDK

func scene(_ scene: UIScene, openURLContexts contexts: Set<UIOpenURLContext>) {
      guard YandexPaySDKApi.isInitialized else { return }
      guard let url = contexts.first?.url else { return }
      YandexPaySDKApi.instance.applicationDidReceiveOpen(url, options: [:])
}

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
      guard YandexPaySDKApi.isInitialized else { return }
      YandexPaySDKApi.instance.applicationDidReceiveUserActivity(userActivity)
}
Стало:

import YandexPayConfiguration  // ← изменено

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
      guard YPay.isInitialized else { return false }  // ← изменено
      YPay.instance.deeplinkHandler.handleOpenURL(url)  // ← изменено
      return true
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity,
                  restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
      guard YPay.isInitialized else { return false }  // ← изменено
      YPay.instance.deeplinkHandler.handleUserActivity(userActivity)  // ← изменено
      return true
}
import YandexPayConfiguration  // ← изменено

func scene(_ scene: UIScene, openURLContexts contexts: Set<UIOpenURLContext>) {
      guard YPay.isInitialized else { return }  // ← изменено
      contexts.map(\.url).forEach { url in
         YPay.instance.deeplinkHandler.handleOpenURL(url)  // ← изменено
      }
}

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
      guard YPay.isInitialized else { return }  // ← изменено
      YPay.instance.deeplinkHandler.handleUserActivity(userActivity)  // ← изменено
}

Важно

Всегда проверяйте YPay.isInitialized перед обращением к YPay.instance. SceneDelegate может получить URL до момента инициализации SDK.

Шаг 5. Миграция кнопки и формы оплаты (Redirect)

Функциональность кнопки и формы оплаты перенесена в модуль YandexPayWithRedirect. Доступ осуществляется через YPay.instance.payWithRedirect.

Кнопка оплаты

1. Создание и конфигурация кнопки.

Было:

import YandexPaySDK

let button: UIView = YandexPaySDKApi.instance.createButton(
   model: YPButtonModel(
      amount: 1000,
      currency: .rub,
      preferredPaymentMethods: [.card, .split],
      appearance: .system,
      cornerRadius: 16,
      isLoading: false,
      isBordered: false
   ),
   paymentDataProvider: self,
   presentationContextProvider: self,
   delegate: self
)
Стало:

import YandexPayWithRedirect  // ← изменено

let button: UIView = YPay.instance.payWithRedirect.createButton(  // ← изменено
   model: YPButtonModel(
      amount: 1000,
      currency: .rub,
      preferredPaymentMethods: [.card, .split],
      // appearance удален — тема задается глобально в YPay.initialize
      cornerRadius: 16,
      isLoading: false,
      isBordered: false
   ),
   paymentDataProvider: self,
   presentationContextProvider: self,
   delegate: self
)

Примечание

Параметр appearance удален из YPButtonModel. Тема кнопки теперь определяется глобальным параметром theme, переданным в YPay.initialize.

2. Протокол делегата для кнопки.

Было:

extension MyViewController: YandexPayButtonDelegate {
   func yandexPayButton(
      _ button: YandexPayButtonProtocol,
      didCompletePaymentWithResult result: YPYandexPayPaymentResult,
      data: YPYandexPayPaymentData
   ) {
      // обработка результата
   }
}
Стало:

extension MyViewController: YPButtonDelegate {  // ← изменено
   func yandexPayButton(
      _ button: any YPButtonProtocol,  // ← изменено
      didCompletePaymentWithResult result: YPPaymentResult,  // ← изменено
      data: YPPaymentData  // ← изменено
   ) {
      // обработка результата
   }
}

3. Провайдер данных для кнопки.

Было:

extension MyViewController: YPButtonPaymentDataProviding {
   func paymentUrl(for yandexPayButton: YandexPayButtonProtocol) async throws -> String {
      // ...
   }
}
Стало:

extension MyViewController: YPButtonPaymentDataProviding {
   func paymentUrl(for yandexPayButton: any YPButtonProtocol) async throws -> String {  // ← изменено
      // ...
   }
}

Форма оплаты

1. Создание и конфигурация формы.

Было:

import YandexPaySDK

let form: YandexPayForm = YandexPaySDKApi.instance.createYandexPayForm(
   paymentURL: url,
   delegate: self
)
Стало:

import YandexPayWithRedirect  // ← изменено

let form: YPForm = YPay.instance.payWithRedirect.createYandexPayForm(  // ← изменено
   paymentURL: url,
   delegate: self
)
form.present(anchor: .keyWindow, animated: true, completion: nil)  // ← добавлено

2. Протокол делегата для формы.

Было:

extension MyViewController: YandexPayFormDelegate {
   func yandexPayForm(
      _ form: YandexPayForm,
      data: YPYandexPayPaymentData,
      didCompletePaymentWithResult result: YPYandexPayPaymentResult
   ) {
      // обработка результата
   }
}
Стало:

extension MyViewController: YPFormDelegate {  // ← изменено
   func yandexPayForm(
      _ payForm: YPForm,  // ← изменено
      data: YPPaymentData,  // ← изменено
      didCompletePaymentWithResult result: YPPaymentResult  // ← изменено
   ) {
      // обработка результата
   }
}

Шаг 6. Миграция бейджей (Inventory)

Функциональность бейджей перенесена в модуль YandexPayInventory. Доступ осуществляется через YPay.instance.inventory.

1. Создание и конфигурация бейджа.

Было:

import YandexPaySDK

let badge: UIView = YandexPaySDKApi.instance.createBadgeView(
   model: YPBadgeModel(
      amount: 1000,
      currency: .rub,
      theme: .system,
      align: .center,
      type: .cashback(color: .primary, variant: .default)
   )
)
Стало:

import YandexPayInventory  // ← изменено

let badge: UIView = YPay.instance.inventory.createBadgeView(  // ← изменено
   model: YPBadgeModel(
      amount: 1000,
      currency: .rub,
      // theme удален — тема задается глобально в YPay.initialize
      align: .center,
      type: .cashback(color: .primary, variant: .default)
   )
)

Примечание

Параметр theme удален из YPBadgeModel. Тема теперь определяется глобально — параметром theme, переданным в YPay.initialize.

2. Тип бейджа.

Было:

.ultimate(variant: .default, payload: nil)
Стало:

  • В описание типа бейджа добавлен новый обязательный параметр mode.
  • Добавлен новый тип бейджа .ultimateSplit.
.ultimate(variant: .default, payload: nil, mode: .auto)
.ultimateSplit(variant: .default, payload: nil, mode: .auto) // новый тип

Справочник: переименованные типы

Старый тип Новый тип
YandexPaySDKApi YPay
YandexPaySDKConfiguration параметры YPay.initialize(...)
YandexPaySDKMerchant YPSDKMerchant
YandexPaySDKEnvironment YPSDKEnvironment
YandexPaySDKLocale YPSDKLocale
YandexPaySDKApi.instance YPay.instance
YandexPaySDKApi.isInitialized YPay.isInitialized
YandexPayForm YPForm
YandexPayFormDelegate YPFormDelegate
YandexPayButtonProtocol YPButtonProtocol
YandexPayButtonDelegate YPButtonDelegate
YPYandexPayPaymentResult YPPaymentResult
YPYandexPayPaymentData YPPaymentData
applicationDidReceiveOpen(_:options:) deeplinkHandler.handleOpenURL(_:)
applicationDidReceiveUserActivity(_:) deeplinkHandler.handleUserActivity(_:)