Руководство по iOS SDK
Важно
Поддерживаемая версия iOS SDK: 14.0 и выше.
Этот способ интеграции требует настройки API. Подробнее о способах интеграции см. Интеграция.
Подключение
Перед началом интеграции нужно получить и добавить в проект несколько идентификаторов:
- Merchant ID
- Client ID (
YANDEX_CLIENT_ID
) - iOS Appid
Шаг 1. Настройка авторизации
1.1 Получите Client ID
-
Для регистрации приложения перейдите в сервис Яндекс OAuth.
-
В поле Название вашего сервиса укажите название, которое будет видно пользователям на экране авторизации.
-
В разделе Платформы приложения выберите iOS-приложение и укажите его параметры:
- iOS Appid — точный идентификатор iOS-приложения, например
A1B2C3D4E5.com.domain.application
, который состоит из Prefix и Bundle ID; - iOS AppStore URL — ссылка на приложение в AppStore.
Примечание
Подробнее про идентификаторы iOS-приложений читайте в документации Apple.
- iOS Appid — точный идентификатор iOS-приложения, например
-
Убедитесь, что на Яндекс OAuth у вашего приложения добавлен доступ к Яндекс Пэй. Для этого в блоке Доступ к данным в поле Название доступа выберите Оплата через Yandex Pay.
-
Нажмите кнопку Создать приложение и скопируйте значение поля Client ID.
-
В разделе Настройки личного кабинета Яндекс Пэй укажите значения Client ID и iOS Appid в полях Client ID и appID для iOS соответственно.
1.2 Настройте Info.plist
Добавьте в файл Info.plist
строки:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>primaryyandexloginsdk</string>
<string>secondaryyandexloginsdk</string>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>YandexLoginSDK</string>
<key>CFBundleURLSchemes</key>
<array>
<string>yx$(YANDEX_CLIENT_ID)</string>
</array>
</dict>
</array>
1.3 Настройте Entitlements
Сервис авторизации обменивается информацией с приложениями Яндекса через Universal Links.
Добавьте следующие строки в Capability: Associated Domains
или файл *.entitlements
:
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yx$(YANDEX_CLIENT_ID).oauth.yandex.ru</string>
<string>applinks:$(YANDEX_CLIENT_ID).merchant.applink.pay.yandex.ru</string>
<string>applinks:$(YANDEX_CLIENT_ID).merchant.applink.sandbox.pay.yandex.ru</string>
</array>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yx$(YANDEX_CLIENT_ID).oauth.yandex.ru</string>
<string>applinks:$(YANDEX_CLIENT_ID).merchant.applink.pay.yandex.ru</string>
</array>
Шаг 2. Установка Yandex Pay SDK
Важно
Текущая версия YandexPaySDK - 1.13.0.
Добавьте зависимость в Podfile:
pod 'YandexPaySDK/Static'
В окне Xcode навигатора проектов Project Navigator выберите свой проект (если у вас используется Workspace). Затем в верхнем меню нажмите File и выберите Add Package Dependencies....
Добавьте пакет по ссылке:
https://github.com/yandexmobile/yandex-pay-ios
Внимание
На текущий момент поддерживается только динамическая библиотека, которая включает все необходимые зависимости. Распространение исходным кодом недоступно из-за ограничений, связанных с PCI DSS.
Добавьте package зависимость в Package.swift:
let package = Package(
...
dependencies: [
.package(
name: "YandexPaySDK",
url: " https://github.com/yandexmobile/yandex-pay-ios"
),
],
...
)
Внимание
На текущий момент есть поддержка только динамической библиотеки, которая включает все необходимые зависимости. Распространение исходным кодом недоступно из-за ограничений, связанных с PCI DSS.
Шаг 3. Инициализация Yandex Pay SDK
Инициализируйте SDK в AppDelegate.swift
вашего проекта в методе application(_:didFinishLaunchingWithOptions:)
:
import YandexPaySDK
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
// Укажите конфигурацию
let merchant = YandexPaySDKMerchant(
// ID продавца в системе Яндекс Пэй
id: "MERCHANT_ID",
// Имя продавца
name: "MERCHANT_NAME",
// URL продавца
url: "https://example.org/"
)
let configuration = YandexPaySDKConfiguration(
// Необходимое окружение
environment: .sandbox,
// Информация о мерчанте
merchant: merchant,
// Локализация
locale: .ru
)
// Инициализируйте SDK
try YandexPaySDKApi.initialize(configuration: configuration)
} catch {
// Отреагируйте на ошибку должным образом
assertionFailure("Unable to initialize YandexPaySDKApi.")
}
// Инициализируйте UIWindow и ViewController
let controller = PaymentURLViewController()
let window = UIWindow(frame: UIScreen.main.bounds)
window.rootViewController = controller
window.makeKeyAndVisible()
self.window = window
return true
}
import YandexPaySDK
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
return
}
do {
// Укажите конфигурацию
let merchant = YandexPaySDKMerchant(
// ID продавца в системе Яндекс Пэй
id: "MERCHANT_ID",
// Имя продавца
name: "MERCHANT_NAME",
// URL продавца
url: "https://example.org/"
)
let configuration = YandexPaySDKConfiguration(
// Необходимое окружение
environment: .sandbox,
// Информация о мерчанте
merchant: merchant,
// Локализация
locale: .ru
)
// Инициализируйте SDK
try YandexPaySDKApi.initialize(configuration: configuration)
} catch {
// Отреагируйте на ошибку должным образом
assertionFailure("Unable to initialize YandexPaySDKApi.")
}
let window = UIWindow(windowScene: windowScene)
window.rootViewController = PaymentURLViewController()
window.makeKeyAndVisible()
self.window = window
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
// Укажите конфигурацию
let merchant = YandexPaySDKMerchant(
// ID продавца в системе Яндекс Пэй
id: "MERCHANT_ID",
// Имя продавца
name: "MERCHANT_NAME",
// URL продавца
url: "https://example.org/"
)
let configuration = YandexPaySDKConfiguration(
// Необходимое окружение
environment: .sandbox,
// Информация о мерчанте
merchant: merchant,
// Локализация
locale: .ru
)
// Инициализируйте SDK
try YandexPaySDKApi.initialize(configuration: configuration)
} catch {
// Отреагируйте на ошибку должным образом
assertionFailure("Unable to initialize YandexPaySDKApi.")
}
// Инициализируйте UIWindow и ViewController
let window = UIWindow()
window.rootViewController = PaymentURLViewController()
window.makeKeyAndVisible()
self.window = window
return true
}
Также в AppDelegate.swift
вашего проекта добавьте нотификацию YandexPaySDK
о событиях жизненного цикла приложения:
import YandexPaySDK
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// Проверьте, что SDK проинициализирован
guard YandexPaySDKApi.isInitialized else {
assertionFailure("YandexPaySDK is not initialized.")
return false
}
return YandexPaySDKApi.instance.applicationDidReceiveUserActivity(userActivity)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
// Проверьте, что SDK проинициализирован
guard YandexPaySDKApi.isInitialized else {
assertionFailure("YandexPaySDK is not initialized.")
return false
}
return YandexPaySDKApi.instance.applicationDidReceiveOpen(url, options: options)
}
import YandexPaySDK
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
// Проверьте, что SDK проинициализирован
guard YandexPaySDKApi.isInitialized else {
assertionFailure("YandexPaySDK is not initialized.")
return false
}
YandexPaySDKApi.instance.applicationDidReceiveUserActivity(userActivity)
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
// Проверьте, что SDK проинициализирован
guard YandexPaySDKApi.isInitialized else {
assertionFailure("YandexPaySDK is not initialized.")
return false
}
guard
let context = URLContexts.first
else { return }
YandexPaySDKApi.instance.applicationDidReceiveOpen(
context.url,
options: [.sourceApplication: context.options.sourceApplication as Any]
)
}
Примеры использования
Для ознакомления доступен демо-проект. В нем есть пример настройки проекта, а также два вида интеграции:
- кнопка Яндекс Пэй с вызовом формы оплаты при ее нажатии (PaymentURLViewController);
- программный вызов формы оплаты из кода (PaymentURLFormViewController).
Добавление кнопки Яндекс Пэй с созданием заказа по ссылке на экран в Swift-проекте
Если вы хотите создать кнопку с новым методом создания заказа, используйте сигнатуру createButton(dataSource:delegate:)
класса YandexPaySDKApi
.
Пример использования кнопки во ViewController
:
import YandexPaySDK
final class PaymentURLViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
// Проверьте, что SDK проинициализирован
guard YandexPaySDKApi.isInitialized else {
assertionFailure("YandexPaySDK is not initialized.")
return
}
// Настройте отображение кнопки
let buttonModel = YPButtonModel(
amount: 1000,
currency: .rub,
preferredPaymentMethods: [.card, .split],
appearance: .system,
cornerRadius: 16,
isLoading: false,
isBordered: false
)
// Создайте кнопку
let button: UIView = YandexPaySDKApi.instance.createButton(
model: buttonModel,
paymentDataProvider: self,
presentationContextProvider: self,
delegate: self
)
// Добавьте кнопку в иерархию
view.addSubview(button)
// Установите layout для кнопки
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view. centerXAnchor),
button.centerYAnchor.constraint(equalTo: view. centerYAnchor),
button.widthAnchor.constraint(equalToConstant: 250)
])
}
}
Кнопка для взаимодействия с клиентским приложением использует делегат YandexPayButtonDelegate
. Реализуйте этот делегат, чтобы передать его кнопке при ее создании:
extension PaymentURLViewController: YandexPayButtonDelegate {
func yandexPayButton(
_ button: YandexPayButtonProtocol,
didCompletePaymentWithResult result: YPYandexPayPaymentResult,
data: YandexPaySDK.YPYandexPayPaymentData
) {
let title: String
let message: String
switch result {
case .succeeded:
title = "Success!"
message = "Payment successfuly proceeded."
case .cancelled:
title = "Cancelled!"
message = "Payment has been cancelled by user."
case .failed:
fallthrough
@unknown default:
title = "Error!"
message = "An error occured while payment processing."
}
let controller = UIAlertController(title: title, message: message, preferredStyle: .alert)
controller.addAction(UIAlertAction(title: "OK", style: .default))
present(controller, animated: true)
}
}
В этом примере мы показываем пользователю сообщение с текущим статусом оплаты через YandexPay.
Кнопка использует протоколы datasource YPButtonPaymentDataProviding
и YPButtonPresentationContextProviding
. Реализуйте указанные протоколы, чтобы передать их кнопке при ее создании:
// MARK: - YPButtonPaymentDataProviding
extension PaymentURLViewController: YPButtonPaymentDataProviding {
func paymentUrl(for yandexPayButton: YandexPayButtonProtocol) async throws -> String {
// Запросите paymentUrl (создайте заказ) асинхронно с вашего бэкенда
await withCheckedContinuation { continuation in
// Это пример реализации async кода, скорее всего, здесь будет сетевой запрос
DispatchQueue.main.async {
continuation.resume(returning: "payment-url.ru")
}
}
}
}
// MARK: - YPButtonPresentationContextProviding
extension PaymentURLViewController: YPButtonPresentationContextProviding {
func anchorForPresentation(for yandexPayButton: any YandexPayButtonProtocol) -> YPPresentationContext {
// Предоставьте UIViewController, с которого необходимо показать форму YandexPay по нажатию на кнопку
.viewController(self)
}
}
Все методы запроса данных являются асинхронными. Это значит, что они должны работать с подходом Swift Concurrency. Если есть необходимость, можно вернуть значение сразу.
Примечание
Смотрите также пример от Apple с WWDC 2021, как перевести элементы вашего кода c подхода GCD на подход Concurrency: Swift concurrency: Update a sample app.