Интеграция SDK
1. Отобразить экран оформления заказа
Этот экран предоставляет пользователю возможность проверить заказанные товары и общую сумму заказа, выбрать время и адрес доставки. На этом экране должна быть кнопка "Оплатить", которая непосредственно создаёт сам заказ.
- iOS
- Android
- Flutter
2. Вызвать метод своего бэкенда для создания заказа
При нажатии на кнопку вызовите метод своего бэкенда, созданный по инструкции в Подготовка бэкенда. Он создаст заказ и вернёт order_access_token
.
- iOS
- Android
- Flutter
func didTapButton() {
api.startPayment(for: order) { result in
// ...
}
}
Пример получения токена заказа с использованием Kotlin Coroutines:
fun getOrderToken() {
...
scope.launch(Dispatchers.IO) {
val order = myRepository.checkout()
this.orderAccessToken = order.orderAccessToken
}
...
}
ElevatedButton(
onPressed: () async {
// Создаём заказ при нажатии на кнопку и сохраняем order_access_token
final orderAccessToken = await MyBackend.createOrder();
},
child: const Text('Оформить'),
);
3. Вызвать метод оплаты в SDK
После получения order_access_token
вызовите метод запуска сценария оплаты. Метод отображает форму оплаты и экран результата оплаты. При необходимости отображает форму 3DSecure.
- iOS
- Android
- Flutter
Вызовите метод Ioka.shared.startPaymentFlow()
, передав туда order_access_token
и другие необходимые параметры.
func didTapButton() {
api.startPayment(for: order) { result in
switch result {
case .success(let response):
Ioka.shared.startPaymentFlow(sourceViewController: self, orderAccessToken: response.orderAccessToken) { _ in
// ...
}
//...
}
}
}
Экраны, которые отображаются в рамках сценария оплаты в ioka SDK:
// activity - Activity, из которого стартует флоу оплаты
// orderAccessToken получаем из сервиса мерчанта
// Configuration - класс для кастомизации UI-компонентов
Ioka.startPaymentFlow(activity: Activity, orderAccessToken: String, configuration: Configuration? = null)
Экраны, которые отображаются в рамках сценария оплаты в ioka SDK:
Вызовите метод Ioka.instance.startCheckoutFlow()
, передав туда context
и order_access_token
.
ElevatedButton(
onPressed: () async {
// Создаём заказ при нажатии на кнопку и сохраняем order_access_token
final orderAccessToken = await MyBackend.createOrder();
// Начинаем оплату - передаём этот токен и контекст в [startCheckoutFlow]
await Ioka.instance.startCheckoutFlow(
context: context,
orderAccessToken: orderAccessToken,
);
// Закрываем страницу оформления заказа
Navigator.pop(context);
},
child: const Text('Оформить'),
);
Экраны, которые отображаются в рамках сценария оплаты в ioka SDK:
3.1. Обработка результата
ioka SDK отображает результат оплаты в своём интерфейсе. После того, как пользователь закрывает экран результата оплаты, результат передаётся вам, чтобы вы могли его обработать. Например, очистить корзину при успешной оплате.
- iOS
- Android
- Flutter
Метод startPaymentFlow
принимает completion
блок, в который передаётся результат оплаты.
func didTapButton() {
api.startPayment(for: order) { result in
switch result {
case .success(let response):
Ioka.shared.startPaymentFlow(sourceViewController: self, orderAccessToken: response.orderAccessToken) { result in
switch result {
case .succeeded:
// Ваша логика для успешной оплаты. Например, очистка корзины.
case .failed(let error):
// Ваша логика для неудачной оплаты.
case .cancelled:
// Ваша логика для закрытия пользователем экрана оплаты.
}
}
// ...
}
}
}
Для отправки результата на вызывающий Activity
мы используем метод Activity.startActivityForResult()
. Для передачи результата используется sealed класс FlowResult
:
/**
* Класс используется для отправки результата до активити мерчанта
* Любой флоу имеет три варианта исхода:
*
* [Succeeded] - флоу завершен успешно, пример: карта сохранена успешно
* [Failed] - флоу завершен неуспешно, пример: не удалось оплатить платеж
* @param [cause] - причина ошибки
* [Cancelled] - пользователь завершил флоу вручную, пример: вернулся на страницу мерчанта по нажатию "Назад"
*/
sealed class FlowResult {
object Succeeded : FlowResult()
class Failed(val cause: String) : FlowResult()
object Cancelled : FlowResult()
}
Поэтому для получения результата оплаты (Succeeded, Cancelled, Failed), переопределите метод onActivityResult()
. requestCode
для флоу оплаты банковской картой используется публичная константа IOKA_PAYMENT_REQUEST_CODE
(можете импортировать из ioka SDK). Пример получения результата:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
...
if (requestCode == IOKA_PAYMENT_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
val result = data?.getParcelableExtra<FlowResult>(IOKA_EXTRA_RESULT_NAME)
result?.let {
if (it is FlowResult.Succeeded)
// Оплата прошла успешно
else if (it is FlowResult.Failed)
// Оплата прошла неуспешно
}
} else if (resultCode == RESULT_CANCELED) {
// Флоу оплаты завершен пользователем, пример: нажал "Назад"
}
}
}
Метод startCheckoutFlow
возвращает Future
типа ExtendedPayment
- подробнее об этом классе можно прочитать в документации API.
В случае, если пользователь прервал оплату, то функция возвращает null
.
ElevatedButton(
onPressed: () async {
// Создаём заказ при нажатии на кнопку и сохраняем order_access_token
final orderAccessToken = await MyBackend.createOrder();
// Начинаем оплату - передаём этот токен и контекст в [startCheckoutFlow]
// Сохраняем результат оплаты в [result]
final result = await Ioka.instance.startCheckoutFlow(
context: context,
orderAccessToken: orderAccessToken,
);
if (result != null) {
// Возможно прошла оплата - необходимо проверить [result.status]
if (result.status == PaymentStatus.captured ||
result.status == PaymentStatus.approved) {
// Успешно проведена оплата, например, очищаем корзину
Provider.of<CartProvider>().clear();
}
else {
// Оплата не прошла и пользователь решил не повторять попытку
}
}
else {
// Пользователь отменил оплату
}
// Закрываем страницу оформления заказа
Navigator.pop(context);
},
child: const Text('Оформить'),
);