IOS SDK
SDK (Software Development Kit) для IOS— это набор инструментов, библиотек и документации, предназначенных для разработки приложений под операционную систему Android. SDK IOS может использоваться для интеграции с API платежных систем. Он предоставляет инструменты и библиотеки, которые помогают разработчикам создавать приложения, способные взаимодействовать с платежными API.
V2 - новая версия
1 Подключение sdk
2 Flutter - дополнительные шаги интеграции
3 Подключение нативного ApplePay
4 API создания платежа
5 API формы стандартного флоу
6 API ApplePay
7 API сохраненных карт
1 Подключение sdk
- SPM -> GitHub - developerslicense/apay-ios
- Нужно добавить конфиги в info.plist
KEY -> Privacy - Face ID Usage Description
TYPE -> String
VALUE -> “Запрос доступа к сохраненным картам”
KEY -> Privacy - Privacy - Camera Usage Description
TYPE -> String
VALUE -> “Предоставьте разрешение для использования сканнера банковских карт”
- Нужно добавить
import AirbaPay
****в файлеApp
и в месте использования в приложении. ВApp
нужно выполнитьрегистрацию шрифтов
при инициализации.
@main
struct TestApp: App {
init() {
AirbaPayFonts.registerCustomFonts()
~~~
}
Для инициализации sdk нужно выполнить AirbaPaySdk.initSdk()
. Функция возвращает экземпляр класса AirbaPaySdk.
Параметр | Тип | Описание |
---|---|---|
isProd* | bool | Продовская или тестовая среда airbapay |
lang* | AirbaPaySdk.Lang | Код языка для UI |
phone* | string | Телефон пользователя |
userEmail | string | Емейл пользователя, куда будет отправлена квитанция. В случае отсутствия емейла |
colorBrandMain | Color | Брендовый цвет кнопок, переключателей и текста |
colorBrandInversion | Color | Цвет текста у кнопок с брендовым цветом |
enabledLogsForProd | bool | Флаг для включения логов |
needDisableScreenShot | Bool | Флаг включения/отключения защиты от скриншота страниц. По дефолту выключен |
actionOnCloseProcessing* | @escaping (Bool?, UINavigationController) -> Void | Замыкание для возврата в приложение. Bool - результат успех или ошибка. UINavigationController - для вызова функций возврата |
openCustomPageSuccess | (() -> Void)? | Замыкание для перехода на кастомную страницу успеха |
openCustomPageFinalError | (() -> Void)? | Замыкание для перехода на кастомную страницу финальной ошибки |
let airbaPaySdk = AirbaPaySdk.initSdk(
isProd: false,
lang: AirbaPaySdk.Lang.RU(),
phone: PHONE,
userEmail: "test@test.com",
colorBrandMain: Color.red,
actionOnCloseProcessing: { isSuccess, navigation in
navigation.present(~)
}
)
2 Flutter - дополнительные шаги интеграции
- В dart добавьте:
final MethodChannel channel = MethodChannel("com.example.testFlutter/AirbaPayChannel");
Future<void> callNativeMethod() async {
try {
await channel.invokeMethod('pay');
} catch (e) {
print('Error calling native method: $e');
}
}
И нужно вызвать callNativeMethod
для перехода на страницы SDK.
- Создайте файл
AirbaPayHandler
import Foundation;
import Flutter;
import SwiftUI;
func handleAirbaPayChannel(
_ app: AppDelegate,
_ call: FlutterMethodCall,
_ result: OneShotFlutterResult
) {
if call.method == "pay" {
let airbaPaySdk = AirbaPaySdk.initSdk(
~
actionOnCloseProcessing: { result, uiNavigationController in
// Здесь нужно использовать OneShotFlutterResult для возврата результата
// и закрытия сдк через uiNavigationController.dismiss(animated: false) или другие способы
)
)
airbaPaySdk.standardFlow(
isApplePayNative: true,
applePayMerchantId: "merchant.~",
shopName: "Shop Name"
)
} else {
result.submit(FlutterMethodNotImplemented)
}
}
class OneShotFlutterResult {
private var result: FlutterResult?
init(_ result: @escaping FlutterResult) {
self.result = result
}
func submit(_ data: Any) {
if (result != nil) {
result!(data)
result = nil
}
}
}
- Добавьте в
AppDelegate
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let airbaPayChannel = FlutterMethodChannel(
name: "com.example.testFlutter/AirbaPayChannel",
binaryMessenger: controller.binaryMessenger
)
airbaPayChannel.setMethodCallHandler({ call, result -> Void in
handleAirbaPayChannel(self, call, OneShotFlutterResult(result))
})
3 Подключение нативного ApplePay
Добавить параметры в
standardFlow()
isApplePayNative: true
applePayMerchantId: "merchant.~"
shopName: "Shop Name"
Перейти в консоль ApplePay https://developer.apple.com/account/resources/identifiers/list
Добавьте в Certificates
1й Type -> Apple Pay Payment Processing Certificate Name -> merchant...pf
2й Type -> Apple Pay Merchant Identity Certificate Name -> merchant...pf
3й Type -> Apple Pay Payment Processing Certificate Name -> merchant...spf
4й Type -> Apple Pay Merchant Identity Certificate Name -> merchant...spf
Перейти во внутрь идентификатора приложения. Поставьте галочку в
Apple Pay Payment Processing
и кликните editВыберите
- Apple Pay Prod Service merchant.~.pf
- Apple Pay Test Service merchant.~.spf
и нажмите continue
Нажмите Save
Зайдите в XCode в Targets -> Signing & Capabilities добавьте Apple Pay айди мерчантов поставьте галочки
4 API создания платежа
Запрос на авторизацию в системе AirbaPay через передачу логина, пароля и айди терминала. Возвращает токен. authPassword()
Параметр | Тип | Описание |
---|---|---|
terminalId* | String | ID терминала под которым создаётся платеж |
shopId* | String | ID магазина в системе AirbaPay |
password* | String | Пароль в системе AirbaPay |
paymentId | String? | ID платежа. В абсолютном большинстве случаев в этом запросе будет null. Нужен для обновления токена с новым paymentId |
onSuccess* | @escaping (String) -> Void | Лямбда на успех. Возвращает токен |
onError* | @escaping () -> Void | Лямбда на ошибку |
airbaPaySdk.authPassword(
terminalId: "123qdfssdf",
shopId: "test",
password: "test123!"
onSuccess: { token in ~ },
onError: { ~ }
)
Запрос на авторизацию в системе AirbaPay через передачу JWT. authJwt()
Параметр | Тип | Описание |
---|---|---|
jwt* | String | JWT токен |
onSuccess* | @escaping () -> Void | Лямбда на успех. |
onError* | @escaping () -> Void | Лямбда на ошибку |
airbaPaySdk.authJwt(
onSuccess: { ~ },
onError: { ~ },
jwt: "~"
)
Запрос на инициализацию платежа в системе AirbaPay. Возвращает AirbaPaySdk.CreatePaymentResult
. createPayment()
Параметр | Тип | Описание |
---|---|---|
authToken* | String | Токен, полученный из auth или другой реализацией получения токена |
failureCallback* | String | URL вебхука при ошибке |
successCallback* | String | URL вебхука при успехе |
purchaseAmount* | Double | Сумма платежа |
accountId* | String | ID аккаунта пользователя |
invoiceId* | String | ID платежа в системе магазина |
orderNumber* | String | Номер заказа в системе магазина |
onSuccess* | (AirbaPaySdk.CreatePaymentResult) -> Void | Лямбда на успех. Возвращает AirbaPaySdk.CreatePaymentResult |
onError* | () -> Void | Лямбда на ошибку |
renderApplePay | Bool? | Флаг настройки показа функционала ApplePay в стандартном флоу. NULL - параметры с сервера |
renderSavedCards | Bool? | Флаг настройки показа функционала сохраненных карт в стандартном флоу. NULL - параметры с сервера |
renderSecurityBiometry | Bool? | Флаг глобальной настройки в сдк для биометрии при оплате сохраненной картой или ApplePay. NULL - параметры с сервера |
renderSecurityCvv | Bool? | Флаг глобальной настройки в сдк для показа боттомщита с CVV при оплате сохраненной картой. NULL - параметры с сервера |
autoCharge | Int | Автоматическое подтверждение при 2х-стадийном режиме 0 - нет, 1 - да |
goods | [AirbaPaySdk.Goods] | Список продуктов для оплаты. Если есть необходимость передачи списка товаров в систему |
settlementPayments | [AirbaPaySdk.SettlementPayment] | Распределение платежа по компаниям. В случае одной компании, может быть null |
airbaPaySdk.createPayment(
authToken: token,
failureCallback: "https://site.kz/failure-clb",
successCallback: "https://site.kz/success-clb",
purchaseAmount: 1500.45,
accountId: "77061111112",
invoiceId: "1111111111",
orderNumber: "ab1111111111"
onSuccess: { result -> ~ },
onError: { ~ }
)
AirbaPaySdk.CreatePaymentResult
Параметр | Тип | Описание |
---|---|---|
token | String? | Обновленный токен |
paymentId | String? | ID созданного платежа |
5 API формы стандартного флоу
Предварительно выполнить airbaPaySdk.authPassword()
вместе с airbaPaySdk.createPayment()
Или выполнить только airbaPaySdk.authJwt()
Есть два варианта реализации стандартного флоу:
standardFlow()
.
Параметр | Тип | Описание |
---|---|---|
isApplePayNative* | Bool | Флаг, определяющий показ нативной кнопки ApplePay вместо вебвьюшки |
applePayMerchantId* | String? | ID мерчанта ApplePay. Нужен для нативной формы. В случае вебверсии NIL |
shopName | String | Название магазина, передающееся в боттомщит ApplePay |
airbaPaySdk.standardFlow(
isApplePayNative: true,
applePayMerchantId: "merchant.~",
shopName: "Shop Name"
)
или для вебверсии ApplePay
airbaPaySdk.standardFlow(
isApplePayNative: false,
applePayMerchantId: nil
)
standardFlowWebView()
Параметр | Тип | Описание |
---|---|---|
isLoadingComplete* | @escaping () -> Void | Замыкание на завершение загрузки данных о платеже |
onError* | @escaping () -> Void | Замыкание на ошибку |
shouldOverrideUrlLoading* | @escaping (AirbaPaySdk.ShouldOverrideUrlLoading) -> Void) | Замыкание, в котором описаны действия на коллбэки с вебвьюшки |
AirbaPaySdk.ShouldOverrideUrlLoading
Параметр | Тип | Описание |
---|---|---|
isCallbackSuccess* | Bool | Флаг, что можно вызвать переход на страницу успеха |
isCallbackBackToApp* | Bool | Флаг, что можно вызвать переход в приложение. true - если была нажата стрелака "назад" или кнопка "Вернуться в магазин" на страницах ошибки |
navAction* | WKNavigationAction | Проброс WKNavigationAction из коллбэка вебвьюшки |
decisionHandler* | (WKNavigationActionPolicy) -> ()) | Проброс (WKNavigationActionPolicy) -> () из коллбэка вебвьюшки |
navController* | UINavigationController | Контроллер навигации |
import WebKit
airbaPaySdk.standardFlowWebView(
isLoadingComplete: { isLoading = false },
shouldOverrideUrlLoading: { obj in
if(obj.navAction.navigationType == .other) {
obj.decisionHandler(.allow)
return
} else {
if let redirectedUrl = obj.navAction.request.url {
if obj.isCallbackSuccess {
// открыть страницу успеха
} else if obj.isCallbackBackToApp {
// клик на кнопку "Вернуться в магазин" или на стрелку "назад"
} else {
obj.decisionHandler(.allow)
return
}
}
}
obj.decisionHandler(.allow)
},
onError: { ~ }
)
6 API ApplePay
Для работы с ApplePay за пределами стандартного флоу:
- Полностью реализовать на стороне приложения механизм вызова ApplePay боттомщита и получения ApplePay токена.
- Выполнить пункт "3 Подключение нативного ApplePay"
- Предварительно выполнить
airbaPaySdk.authPassword()
вместе сairbaPaySdk.createPayment()
Или выполнить толькоairbaPaySdk.authJwt()
- Вызвать после получения токена ApplePay функцию
processExternalApplePay()
Параметр | Тип | Описание |
---|---|---|
applePayToken* | String | Токен ApplePay |
airbaPaySdk.processExternalApplePay(applePayToken: applePayToken)
7 API сохраненных карт
Запрос списка сохраненных карт пользователя getCards()
Предварительно выполнить airbaPaySdk.authPassword()
или airbaPaySdk.authJwt()
Параметр | Тип | Описание |
---|---|---|
onSuccess* | @escaping ([BankCard]) -> Void | Замыкание на успех со списком сохраненных карт |
onNoCards* | @escaping () -> Void | Замыкание на отсутствие сохраненных карт |
Запрос удаления сохраненной карты пользователя deleteCard()
Предварительно выполнить airbaPaySdk.authPassword()
или airbaPaySdk.authJwt()
Параметр | Тип | Описание |
---|---|---|
cardId* | String | ID сохраненной карты |
onSuccess* | @escaping () -> Void | Замыкание на успех |
onError* | @escaping () -> Void | Замыкание на ошибку |
Запрос проведения оплаты по сохраненной карте пользователя paySavedCard()
Предварительно выполнить airbaPaySdk.authPassword()
или airbaPaySdk.authJwt()
Параметр | Тип | Описание |
---|---|---|
isLoading* | @escaping (Bool) -> Void | Замыкание для показа прогрессбара |
onError* | @escaping () -> Void | Замыкание на ошибку |
bankCard* | BankCard | Экземпляр карты, получаемый из запроса getCards |
V1 - первая версия SDK до обновления, для новых партнеров использовать V2.
1.1 Подключение sdk
1.2 Вызов стартовой формы
1.3 Пример использования
1.4 Подключение нативного ApplePay
1.5 Подключение API внешнего взаимодействия с ApplePay (Нативный)
1.6 Подключение API внешнего взаимодействия с ApplePay (Вебвью)
1.7 Рекомендация в случае интеграции в flutter
1.1 Подключение sdk
- SPM -> GitHub - developerslicense/apay-ios
- Нужно добавить конфиги в info.plist
KEY -> Privacy - Face ID Usage Description
TYPE -> String
VALUE -> “Запрос доступа к сохраненным картам”
KEY -> Privacy - Privacy - Camera Usage Description
TYPE -> String
VALUE -> “Предоставьте разрешение для использования сканнера банковских карт”
- Нужно добавить import AirbaPay в файле App и в месте использования в приложении. В App нужно выполнить регистрацию шрифтов при инициализации.
@main
struct TestApp: App {
init() {
AirbaPayFonts.registerCustomFonts()
~~~
}
Для инициализации sdk нужно выполнить
AirbaPaySdk.initSdk()
передвызовом
AirbaPaySdk.startAirbaPay()
.
Параметр | Тип | Описание |
---|---|---|
shopId* | string | ID магазина в системе AirbaPay |
password* | string | Пароль в системе AirbaPay |
terminalId* | string | ID терминала под которым создали платеж |
accountId* | string | ID аккаунта пользователя |
lang | AirbaPaySdk.Lang | Код языка для UI |
isProd | bool | Продовская или тестовая среда airbapay |
phone | string | Телефон пользователя |
failureCallback | string | URL вебхука при ошибке |
successCallback | string | URL вебхука при успехе |
userEmail | string | Емейл пользователя, куда будет отправлена квитанция. В случае отсутствия емейла |
colorBrandMain | Color | Брендовый цвет кнопок, переключателей и текста |
colorBrandInversion | Color | Цвет текста у кнопок с брендовым цветом |
autoCharge | Int | Автоматическое подтверждение при 2х-стадийном режиме 0 - нет, 1 - да |
enabledLogsForProd | м | Флаг для включения логов |
purchaseAmount | Int | Сумма платежа |
invoiceId | string | ID платежа в системе магазина |
orderNumber | string | Номер заказа в системе магазина |
goods | Array<AirbaPaySdk.Goods> | Список продуктов для оплаты |
settlementPayments | Array<AirbaPaySdk.SettlementPayment> | Распределение платежа по компаниям. В случае одной компании, может быть nil |
shopName | string | Название магазина для нативного ApplePay |
isApplePayNative | Bool | Флаг, определяющий показ нативной кнопки ApplePay вместо вебвьюшки |
applePayMerchantId | string | Айдишка мерчанта, прописанная в консоли ApplePay |
needDisableScreenShot | Bool | Флаг включения/отключения защиты от скриншота страниц. По дефолту выключен |
let goods = [
AirbaPaySdk.Goods(
model: "Чай Tess Banana Split черный 20 пирамидок",
brand: "Tess",
category: "Черный чай",
quantity: 1,
price: 1000
)
]
let settlementPayment = [
AirbaPaySdk.SettlementPayment(
amount: 1000,
companyId: "test_id"
)
]
AirbaPaySdk.initSdk(
isProd: false,
lang: AirbaPaySdk.Lang.RU(),
accountId: ACCOUNT_ID_TEST,
phone: PHONE,
userEmail: "test@test.com",
shopId: "test",
password: "123!",
terminalId: "6421c4a48db060dd689",
failureCallback: "https://site.kz/failure-clb",
successCallback: "https://site.kz/success-clb",
colorBrandMain: Color.red,
autoCharge: autoCharge,
purchaseAmount: 1500,
invoiceId: String(someInvoiceId),
orderNumber: String(someOrderNumber),
goods: goods,
settlementPayments: settlementPayment,
isApplePayNative: true,
shopName: "Shop Name",
applePayMerchantId: "merchant.~"
}
1.2 Вызов стартовой формы
Открытие формы AirbaPay выполняется через AirbaPaySdk.startAirbaPay().
Параметр | Тип | Описание |
---|---|---|
isCustomSuccessPageView | Bool | Флаг переключения на кастомную вьюшку успешного кейса |
isCustomFinalErrorPageView | Bool | Флаг переключения на кастомную вьюшку финального неуспешного кейса |
actionOnOpenProcessing | () -> Void | Действие на открытие процессинга |
actionOnCloseProcessing | (Bool) -> Void | Действие на закрытие процессинга с возвратом результата |
@ObservedObject var navigateCoordinator = AirbaPayCoordinator(
actionOnOpenProcessing: { ~ },
actionOnCloseProcessing: { result in ~ },
customSuccessPageView: AnyView(~~~)
)
AirbaPayView
Параметр | Тип | Описание |
---|---|---|
navigateCoordinator* | @ObservedObject AirbaPayCoordinator | Координатор навигации |
contentView* | AnyView? | Контент страницы, на которой будет вызван sdk |
SwiftUi:
Контент страницы приложения обернуть в AirbaPayView
var body: some View {
AirbaPayView(
navigateCoordinator: navigateCoordinator,
contentView: contentView
)
}
Storyboards:
Открыть новую страницу с содержимым swiftUi.
Ниже описан кратко вариант интеграции. Более подробно описано в статье https://sarunw.com/posts/swiftui-view-as-uiview-in-storyboard/
Добавить
Container View
и удалить привязанный к нему дефолтныйViewController
Добавить
UIHostingController
и привязатьContainer View
к нему черезEmbed
Связать это с
ViewController
кодом, указанным в примере:
Пример:
@IBSegueAction func initPage(_ coder: NSCoder) -> UIViewController? {
AirbaPaySdk.initSdk(~)
return UIHostingController(coder: coder, rootView: SwiftUIView(
actionOnClick: {
DispatchQueue.main.async {
let hostingController = UIHostingController(
rootView: AirbaPayView(
navigateCoordinator: self.navigateCoordinator,
contentView: {}
).onAppear {
self.navigateCoordinator.startProcessing()
}
)
self.navigationController?.pushViewController(hostingController, animated: true)
}
},
navigateCoordinator: navigateCoordinator
))
}
struct SwiftUIView: View {
var actionOnClick: () -> Void
@ObservedObject var navigateCoordinator: AirbaPayCoordinator
var body: some View {
Button(
action: actionOnClick,
label: { Text("Продолжить") }
)
}
}
1.3 Пример использования
В случае наличия на странице системных элементов управления (к примеру, кнопки назад), обязательно нужно скрыть их (в случае навигации в swiftUi через .navigationBarBackButtonHidden(true)
)
Пример:
struct TestCustomSuccessPage: View {
var body: some View {
Button(action: {}, label: { Text("TestSuccessPage") })
}
}
struct TestPage: View {
var back: () -> Void
var phone: String = ""
@ObservedObject var navigateCoordinator = AirbaPayCoordinator(
customSuccessPageView: AnyView(TestCustomSuccessPage())
)
var body: some View {
AirbaPayView(
navigateCoordinator: navigateCoordinator,
contentView: {
VStack {
Button(
action: {
AirbaPaySdk.initSdk(~~~)
navigateCoordinator.startProcessing()
},
label: {
Text("переход на эквайринг")
}
)
Spacer()
}
}
)
}
}
1.4 Подключение нативного ApplePay
- Добавить параметры в initSdk
isApplePayNative = true
applePayMerchantId = "merchant.~"
Перейти в консоль ApplePay https://developer.apple.com/account/resources/identifiers/list
Добавьте в Certificates 1й Type -> Apple Pay Payment Processing Certificate Name -> merchant.~.pf
2й Type -> Apple Pay Merchant Identity Certificate Name -> merchant.~.pf
3й Type -> Apple Pay Payment Processing Certificate Name -> merchant.~.spf
4й Type -> Apple Pay Merchant Identity Certificate Name -> merchant.~.spf
Перейти во внутрь идентификатора приложения. Поставьте галочку в Apple Pay Payment Processing и кликните edit
Выберите ~ Apple Pay Prod Service merchant.~.pf ~ Apple Pay Test Service merchant.~.spf и нажмите continue
Нажмите Save
Зайдите в XCode в Targets -> Signing & Capabilities добавьте Apple Pay айди мерчантов поставьте галочки
1.5 Подключение API внешнего взаимодействия с ApplePay (Нативный)
buyBtnTapped
Параметр | Тип | Описание |
---|---|---|
redirectFromStoryboardToSwiftUi | (() -> Void)? | Замыкание перехода в сдк для storyboard |
backToStoryboard | (() -> Void)? | Замыкание возврата в приложение для storyboard |
ApplePayManager
Параметр | Тип | Описание |
---|---|---|
navigateCoordinator* | @ObservedObject AirbaPayCoordinator | Координатор навигации |
SwiftUI:
- Добавить, как указано в примере:
struct TestPage: View {
@ObservedObject var navigateCoordinator = AirbaPayCoordinator(~)
var body: some View {
let applePay = ApplePayManager(navigateCoordinator: navigateCoordinator)
AirbaPayView(
navigateCoordinator: navigateCoordinator,
contentView: {
// контент страницы приложения
~~~
// кнопка продолжения
Button(
action: {
~~~
AirbaPaySdk.initSdk(
~
isApplePayNative: true,
shopName: ~,
applePayMerchantId: "merchant.~"
)
applePay.buyBtnTapped()
}
)
}
)
}
Storyboards:
Внимание! Для storyboard недоступны кастомные страницы завершения
- Добавить импорты во
ViewController
import SwiftUI import AirbaPay
- Добавить
@ObservedObject var navigateCoordinator = AirbaPayCoordinator()
- Дальше надо выполнить ряд действий для подключения вьюшки в storyboard. Ниже описан кратко вариант интеграции. Более подробно описано в статье https://sarunw.com/posts/swiftui-view-as-uiview-in-storyboard/
- Добавить
Container View
и удалить привязанный к нему дефолтныйViewController
- Добавить
UIHostingController
и привязатьContainer View
к нему черезEmbed
- Связать это с
ViewController
кодом, указанным ниже
@IBSegueAction func addApplePay(_ coder: NSCoder) -> UIViewController? {
AirbaPaySdk.initSdk(~)
let applePay = ApplePayManager(navigateCoordinator: navigateCoordinator)
return UIHostingController(coder: coder, rootView: SwiftUIView(
actionOnClick: {
let hostingController = UIHostingController(
rootView: AirbaPayNextStepApplePayView(navigateCoordinator: self.navigateCoordinator)
)
self.navigationController?.pushViewController(hostingController, animated: true)
},
actionOnClose: {
self.navigationController?.popViewController(animated: true)
},
navigateCoordinator: navigateCoordinator,
applePay: applePay
))
}
struct SwiftUIView: View {
var actionOnClick: () -> Void
var actionOnClose: () -> Void
@ObservedObject var navigateCoordinator: AirbaPayCoordinator
let applePay: ApplePayManager
var body: some View {
Button(
action: {
applePay.buyBtnTapped(
redirectFromStoryboardToSwiftUi: actionOnClick,
backToStoryboard: actionOnClose
)
}
)
}
}
1.6 Подключение API внешнего взаимодействия с ApplePay (Вебвью)
Для работы с ApplePay потребуется вьюшка ApplePayWebViewExternal
из AirbaPay.
Визуально она не будет отображаться на экране, т.к. занимает всего 0.1. Вьюшку можно поместить вниз экрана.
Параметр | Тип | Описание |
---|---|---|
redirectFromStoryboardToSwiftUi | (() -> Void)? | Замыкание перехода в сдк для storyboard |
backToStoryboard | (() -> Void)? | Замыкание возврата в приложение для storyboard |
navigateCoordinator* | @ObservedObject AirbaPayCoordinator | Координатор навигации |
isLoading* | @escaping (Bool) -> Void | Замыкание для показа лоадинга или плейсхолдера |
applePayViewModel* | @ObservedObject ApplePayViewModel | ViewModel для работы с эппл пэй из AirbaPay |
SwiftUi:
Примечание: Если вы используете SwiftUi в Storyboards, то применяйте инструкцию для Storyboards.
- Выполнить в
onAppear
AirbaPaySdk.initSdk(~)
- Добавить, как указано в примере:
struct TestPage: View {
@ObservedObject var navigateCoordinator = AirbaPayCoordinator(~)
@ObservedObject var applePayViewModel = ApplePayViewModel()
var body: some View {
AirbaPayView(
navigateCoordinator: navigateCoordinator,
contentView: {
// контент страницы приложения
~~~
// кнопка продолжения
Button(
action: {
~~~
// Нужно показать прогрессбар, т.к. потребуется время для загрузки
applePayViewModel.auth(
onError: {
// Коллбэк для обработки ошибки и скрытия прогрессбара
},
onSuccess: {
// Коллбэк для скрытия прогрессбара
}
)
}
)
ApplePayWebViewExternal(
navigateCoordinator: navigateCoordinator,
applePayViewModel: applePayViewModel
)
}
)
}
Storyboards:
Внимание! Для storyboard недоступны кастомные страницы завершения
- Добавить импорты во
ViewController
import SwiftUI
import AirbaPay
- Добавить
@ObservedObject var navigateCoordinator = AirbaPayCoordinator()
- Дальше надо выполнить ряд действий для подключения вьюшки в storyboard. Ниже описан кратко вариант интеграции. Более подробно описано в статье https://sarunw.com/posts/swiftui-view-as-uiview-in-storyboard/
- Добавить
Container View
и удалить привязанный к нему дефолтныйViewController
- Добавить
UIHostingController
и привязатьContainer View
к нему черезEmbed
- Связать это с
ViewController
кодом, указанным ниже
@IBSegueAction func addApplePay(_ coder: NSCoder) -> UIViewController? {
AirbaPaySdk.initSdk(~)
return UIHostingController(coder: coder, rootView: SwiftUIView(
actionOnClick: {
let hostingController = UIHostingController(
rootView: AirbaPayNextStepApplePayView(navigateCoordinator: self.navigateCoordinator)
)
self.navigationController?.pushViewController(hostingController, animated: true)
},
actionOnClose: {
self.navigationController?.popViewController(animated: true)
},
navigateCoordinator: navigateCoordinator
))
}
struct SwiftUIView: View {
var actionOnClick: () -> Void
var actionOnClose: () -> Void
@ObservedObject var navigateCoordinator = AirbaPayCoordinator()
@ObservedObject var applePayViewModel = ApplePayViewModel()
var body: some View {
ZStack {
Color.gray
Color.white
VStack {
// кнопка продолжения
Button(
action: {
applePayViewModel.auth(
onError: {
// Коллбэк для обработки ошибки и скрытия прогрессбара
},
onSuccess: {
// Коллбэк для скрытия прогрессбара
}
)
}
)
ApplePayWebViewExternal(
redirectFromStoryboardToSwiftUi: actionOnClick,
backToStoryboard: actionOnClose,
navigateCoordinator: navigateCoordinator,
applePayViewModel: applePayViewModel
)
}
}
}
}
1.7 Рекомендация в случае интеграции в flutter
- В dart добавьте:
И нужно вызвать callNativeMethod
для перехода на страницы сдк.
final MethodChannel channel = MethodChannel("com.example.testFlutter/AirbaPayChannel");
Future<void> callNativeMethod() async {
try {
await channel.invokeMethod('pay');
} catch (e) {
print('Error calling native method: $e');
}
}
- Создайте файл
AirbaPayHandler
import Foundation
import Flutter
import AirbaPay
import SwiftUI
func handleAirbaPayChannel(
_ app: AppDelegate,
_ call: FlutterMethodCall,
_ result: OneShotFlutterResult
) {
let controller : FlutterViewController = app.window?.rootViewController as! FlutterViewController
if call.method == "pay" {
let lang: AirbaPaySdk.Lang = AirbaPaySdk.Lang.RU()
let someInvoiceId = ~
let someOrderNumber = ~
let goods = AirbaPaySdk.Goods(
brand: "TechnoFit",
category: "Services",
model: "asdafasfd",
quantity: 1,
price: 5500
)
AirbaPaySdk.initSdk(
isProd: false,
lang: lang,
accountId: "10000001",
phone: "+77050000010",
userEmail: "asdasd@sad.com",
shopId: "test",
password: "123!",
terminalId: "64216e74a48db060dd689",
failureCallback: "https://site.kz/failure-clb",
successCallback: "https://site.kz/success-clb",
autoCharge: 0,
enabledLogsForProd: true,
purchaseAmount: 5500,
invoiceId: String(someInvoiceId),
orderNumber: String(someOrderNumber),
goods: [goods]
)
controller.show(AirbaPayViewController(result: result), sender: controller)
} else {
result.submit(FlutterMethodNotImplemented)
}
}
class OneShotFlutterResult {
private var result: FlutterResult?
init(_ result: @escaping FlutterResult) {
self.result = result
}
func submit(_ data: Any) {
if (result != nil) {
result!(data)
result = nil
}
}
}
- Создайте файл
AirbaPayViewController
import Foundation
import SwiftUI
import AirbaPay
class AirbaPayViewController : UIHostingController<AirbaPayView> {
private var result: OneShotFlutterResult? = nil
init(
result: OneShotFlutterResult
) {
var lateSelf: AirbaPayViewController? = nil
self.result = result
let navigateCoordinator = AirbaPayCoordinator(
actionOnCloseProcessing: { r in
lateSelf?.dismiss(animated: false)
result.submit(["result": r])
}
)
let airbaPayView = AirbaPayView(navigateCoordinator: navigateCoordinator) {}
navigateCoordinator.startProcessing()
super.init(rootView: airbaPayView)
lateSelf = self
view.backgroundColor = UIColor.black.withAlphaComponent(0)
}
required dynamic init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func viewDidDisappear(_ animated: Bool) {
result?.submit(["result": false])
}
override func viewSafeAreaInsetsDidChange() {
print("safe")
}
}
- Добавьте в
AppDelegate
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let airbaPayChannel = FlutterMethodChannel(
name: "com.example.testFlutter/AirbaPayChannel",
binaryMessenger: controller.binaryMessenger
)
airbaPayChannel.setMethodCallHandler({ call, result -> Void in
handleAirbaPayChannel(self, call, OneShotFlutterResult(result))
})