Flutter-SDK

Матеріал з apidocs
Перейти до: навігація, пошук

Введеня


Ця інструкція допоможе вам налаштувати і реалізувати можливості EasyPay SDK у вашому Flutter-додатку як для Android, так і для iOS. Виконуючи кроки в інструкції, ви зможете:

  • Підключити SDK до вашого Flutter-проекту.
  • Реалізувати функціонал для здійснення платежів.
  • Додати можливість перегляду, додавання або видалення карток користувачів.


Незалежно від того, на якій платформі ви працюєте (Android чи iOS), SDK EasyPay забезпечить вам підтримку на обох платформах, дозволяючи вам створювати додатки з потужними платіжними функціями для ваших користувачів.

Android частина


Налаштування залежностей


Відкрийте файл settings.gradle у вашому проекті та додайте наступні налаштування: settings.gradle (рівень проекту):

pluginManagement {
    val flutterSdkPath = run {
        val properties = java.util.Properties()
        file("local.properties").inputStream().use { properties.load(it) }
        val flutterSdkPath = properties.getProperty("flutter.sdk")
        require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
        flutterSdkPath
    }
    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

Це дозволить правильно налаштувати плагіни Flutter і залежності для проекту. build.gradle (рівень додатку):

dependencies {
    implementation("ua.easypay:EasyPay-Sdk:1.0.0-alpha8")
}

Ініціалізація SDK в класі Application

В Android потрібно ініціалізувати EasyPay SDK у класі Application. Створіть або відкрийте ваш клас FlutterApp:

class FlutterApp : Application() {
    override fun onCreate() {
        super.onCreate()
        EasyPaySdk.init(
            context = PlatformContext(this), // ініціалізація контексту
            secret = "your secret", // Ваш секретний ключ
            partnerKey = "your partner key" // Ваш партнерський ключ
        )
    }
}

Цей код ініціалізує SDK при запуску додатку на платформі Android.

Створення MethodChannel для взаємодії з Flutter

На цьому етапі вам потрібно налаштувати MethodChannel, який дозволить вашому Flutter додатку взаємодіяти з нативним кодом Android. Через цей канал ваш додаток зможе надсилати запити на Android для таких операцій, як ініціація процесу оплати чи відкриття екрану для роботи з картками користувача.

package ua.easypay.sdktestapp_flutter.test_app_with_sdk_flutter

import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import ua.easypay.sdk.data.contracts.SdkPaymentContract
import ua.easypay.sdk.data.model.arguments.SdkCardsContractArgs
import ua.easypay.sdk.data.model.arguments.SdkPaymentContractArgs
import ua.easypay.sdk.presentation.SdkUserCardsActivity.Companion.navigate
import ua.easypay.sdk.presentation.instruments.PaymentInstrumentArgs

class MainActivity : FlutterFragmentActivity() {
    private val CHANNEL = "com.example.sdk/payment"
    private var pendingResult: MethodChannel.Result? = null

    private val paymentLauncher = registerForActivityResult(SdkPaymentContract()) { sdkResult ->
        pendingResult?.let { result ->
            result.success(sdkResult?.toString())
            pendingResult = null
        }
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "startPayment") {
                val args = call.arguments as? Map<*, *>
                if (args != null) {
                    try {
                        val serviceKey = args["serviceKey"] as? String ?: throw IllegalArgumentException("Missing serviceKey")
                        val orderId = args["orderId"] as? String ?: throw IllegalArgumentException("Missing orderId")
                        val amount = (args["amount"] as? String)?.toDoubleOrNull() ?: throw IllegalArgumentException("Missing/invalid amount")
                        val description = args["description"] as? String ?: throw IllegalArgumentException("Missing description")
                        val additionalItems = (args["additionalItems"] as? Map<*, *>)?.mapKeys { it.key.toString() }?.mapValues { it.value.toString() }
                        val phoneNumber = args["phoneNumber"] as? String
                        val showPaymentResult = args["showPaymentResult"] as? Boolean ?: false

                        val paymentInstrumentArgs = PaymentInstrumentArgs(
                            serviceKey = serviceKey,
                            orderId = orderId,
                            amount = amount,
                            description = description,
                            additionalItems = additionalItems,
                            phoneNumber = phoneNumber
                        )

                        val sdkArgs = SdkPaymentContractArgs(
                            paymentInstrumentArgs = paymentInstrumentArgs,
                            showPaymentResult = showPaymentResult
                        )
                        pendingResult = result

                        paymentLauncher.launch(sdkArgs)

                    } catch (e: Exception) {
                        result.error("INVALID_ARGS", "Failed to parse args: ${e.localizedMessage}", null)
                    }
                } else {
                    result.error("INVALID_ARGS", "Args were null", null)
                }
            } else if (call.method == "openCardListScreen") {
                val phoneNumber = call.argument<String>("phoneNumber") ?: ""
                val args = SdkCardsContractArgs(phoneNumber = phoneNumber)
                this@MainActivity.navigate(args)
                result.success(null)
            } else {
                result.notImplemented()
            }
        }
    }
}

iOS частина


Підключення SDK

Для підключення SDK до iOS проекту необхідно завантажити EasyPaySdkIos.xcframework і вставити його в папку з проектом ../YourProject/iOS/Runner/.

Перевірте, чи з'явився фреймворк в розділі Frameworks, Libraries, and Embedded Content.

Також додайте папку compose-resources, яка знаходиться всередині EasyPaySdkIos.xcframework, до Copy Bundle Resources.

Важливо: при додаванні compose-resources в діалозі додавання у вас були обрані наступні опції

  • Destination: Copy items if needed
  • Added folders: Create folder references


Ініціалізація SDK в AppDelegate.swift

Імпортування бібліотек. Перше, що вам потрібно зробити, — це імпортувати необхідні бібліотеки:

import Flutter
import UIKit
import EasyPaySdkIos

Ініціалізація SDK в AppDelegate.swift У вашому AppDelegate.swift файлі реалізуйте ініціалізацію EasyPay SDK в методі application(_:didFinishLaunchingWithOptions:). Це дозволить налаштувати SDK при запуску додатку.

@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,

didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
EasyPaySdk.shared.doInit(
context: PlatformContext(),
secret: your secret",
partnerKey: “your partner key",
applePayMerchantId: "merchant.com.example"
)
GeneratedPluginRegistrant.register(with: self)
return super.application(application,
didFinishLaunchingWithOptions: launchOptions)
}
}

Створення MethodChannel для методів навігації на оплату та на перегляд/додавання/видалення карток


У цьому кроці налаштовується MethodChannel для взаємодії між Flutter та нативним кодом iOS. Це дозволяє відправляти запити з Flutter для запуску оплати або відкриття екрану для перегляду, додавання чи видалення карток.

import Flutter
import UIKit
import EasyPaySdkIos
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
EasyPaySdk.shared.doInit(
context: PlatformContext(),
secret: your secret",
partnerKey: “your partner key",
applePayMerchantId: "merchant.com.example"
)
let controller = window?.rootViewController as!
FlutterViewController
let channel = FlutterMethodChannel(name: "com.example.sdk/
payment", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { [weak controller] call, result in
if call.method == "startPayment" {
guard let args = call.arguments as? [String: Any] else {
result(FlutterError(code: "INVALID_ARGS", message:
"Args were null", details: nil))
return
}
let vc = createPaymentVC(args: args) { sdkResult in

if let sdkResult = sdkResult {
result(sdkResult.description) // send result
back to Flutter
} else {
result("Cancelled")
}
}
controller?.present(vc, animated: true)
} else if call.method == "openCardListScreen" {
let phoneNumber = (call.arguments as? [String: Any])?
["phoneNumber"] as? String ?? ""
let vc =
SdkCardsViewControllerKt.SdkCardsViewController(
args: SdkCardsContractArgs(phoneNumber: phoneNumber,
urlToNotifyMerchant: nil)) {
result(nil)
}
controller?.present(vc, animated: true)
} else {
result(FlutterMethodNotImplemented)
}
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application,
didFinishLaunchingWithOptions: launchOptions)
}
}
func createPaymentVC(args: [String: Any], onResult: @escaping
(EPaySdkResult?) -> Void) -> UIViewController{
let params = SdkPaymentContractArgs(
paymentInstrumentArgs: PaymentInstrumentArgs(
serviceKey: args["serviceKey"] as? String ?? "",
orderId: args["orderId"] as? String ?? "",
amount: Double(args["amount"] as? String ?? "0") ?? 0.0,
description: args["description"] as? String ?? "",
additionalItems: (args["additionalItems"] as? [String:
String]) ?? [:],
phoneNumber: args["phoneNumber"] as? String
),
showPaymentResult: args["showPaymentResult"] as? Bool ?? false
)
let vc = SdkPaymentViewControllerKt.SdkPaymentViewController(args:
params) { result in
onResult(result)
}
vc.modalPresentationStyle = .fullScreen
return vc
}

Ініціалізація оплати

SizedBox(
    width: double.infinity,
    child: FloatingActionButton.extended(
        onPressed: () async {
            final args = {
                'serviceKey': 'SomeServiceKey',
                'orderId': 'SomeOrderId',
                'amount': '3.0',
                'description': 'payment description',
                'phoneNumber': '380990000000',
                'showPaymentResult': true,
            };
            try {
                final result = await platform.invokeMethod('startPayment', args);
                setState(() {
                    _paymentResult = result;
                });
            } on PlatformException catch (e) {
                setState(() {
                    _paymentResult = "Failed to get payment result: '${e.message}'.";
                });
            }
        },
        label: const Text('Make payment'),
    ),
)

Перехід на флоу перегляду/додавання/видалення карток

SizedBox(
    width: double.infinity,
    child: FloatingActionButton.extended(
        onPressed: () async {
            final phoneNumber = _phoneNumberController.text;
            try {
                await platform.invokeMethod('openCardListScreen', {
                    'phoneNumber': phoneNumber,
                });
            } on PlatformException catch (e) {
                print('Failed to open card list screen: ${e.message}');
            }
        },
        label: const Text('Navigate to cards'),
    ),
)