Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native Payments SDK implementation #30

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 60 additions & 48 deletions README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk

import androidx.annotation.NonNull
import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewWidgetFactory
import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewPlugin
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
Expand All @@ -20,6 +22,10 @@ public class FlutterKlarnaInappSdk : FlutterPlugin, ActivityAware {
val eventChannel = EventChannel(flutterPluginBinding.flutterEngine.dartExecutor, it.key)
eventChannel.setStreamHandler(it.value)
}

flutterPluginBinding
.platformViewRegistry
.registerViewFactory("plugins/klarna_payment_view", KlarnaPaymentViewWidgetFactory(flutterPluginBinding.binaryMessenger))
}

// This static function is optional and equivalent to onAttachedToEngine. It supports the old
Expand All @@ -46,6 +52,8 @@ public class FlutterKlarnaInappSdk : FlutterPlugin, ActivityAware {

PluginContext.activity = registrar.activity()
PluginContext.context = registrar.context()

KlarnaPaymentViewPlugin.registerWith(registrar)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment

import io.flutter.plugin.common.PluginRegistry

object KlarnaPaymentViewPlugin {
fun registerWith(registrar: PluginRegistry.Registrar) {
registrar
.platformViewRegistry()
.registerViewFactory(
"plugins/klarna_payment_view", KlarnaPaymentViewWidgetFactory(registrar.messenger()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment

import android.content.Context
import android.view.View
import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.PluginContext
import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.core.util.requireArgument
import com.klarna.mobile.sdk.api.payments.KlarnaPaymentCategory
import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView
import io.flutter.Log
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.platform.PlatformView

class KlarnaPaymentViewWidget internal constructor(context: Context, id: Int, messenger: BinaryMessenger, creationParams: Map<String?, Any?>?) : PlatformView, MethodCallHandler {
private val methodChannel: MethodChannel

private val paymentView: KlarnaPaymentView

private val paymentCategories = mapOf(
"pay_now" to KlarnaPaymentCategory.PAY_NOW,
"pay_later" to KlarnaPaymentCategory.PAY_LATER,
"pay_over_time" to KlarnaPaymentCategory.SLICE_IT
)

override fun getView(): View {
return paymentView
}

init {
val paymentCategory = creationParams!!["category"] as String

methodChannel = MethodChannel(messenger, "plugins/klarna_payment_view_$id")
methodChannel.setMethodCallHandler(this)
paymentView = KlarnaPaymentView(PluginContext.context!!, paymentCategories[paymentCategory]!!, KlarnaPaymentSDKCallback(methodChannel))
}

override fun onMethodCall(methodCall: MethodCall, result: Result) {
when (methodCall.method) {
"initialize" -> initialize(methodCall, result)
"load" -> load(methodCall, result)
"authorize" -> authorize(methodCall, result)
"finalize" -> finalize(methodCall, result)
"reauthorize" -> reauthorize(methodCall, result)
"loadPaymentReview" -> loadPaymentReview(methodCall, result)
else -> result.notImplemented()
}
}

private fun initialize(methodCall: MethodCall, result: Result) {
paymentView.initialize(methodCall.requireArgument("clientToken"), methodCall.requireArgument("returnUrl"))
result.success(null)
}

private fun load(methodCall: MethodCall, result: Result) {
paymentView.load(methodCall.argument("args"))
result.success(null)
}

private fun authorize(methodCall: MethodCall, result: Result) {
paymentView.authorize(methodCall.requireArgument("autoFinalize"), methodCall.argument("sessionData"))
result.success(null)
}

private fun finalize(methodCall: MethodCall, result: Result) {
paymentView.finalize(methodCall.argument("sessionData"));
result.success(null)
}

private fun reauthorize(methodCall: MethodCall, result: Result) {
paymentView.reauthorize(methodCall.argument("sessionData"));
result.success(null)
}

private fun loadPaymentReview(methodCall: MethodCall, result: Result) {
paymentView.loadPaymentReview();
result.success(null)
}

override fun dispose() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment

import android.content.Context
import com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment.KlarnaPaymentViewWidget
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory

class KlarnaPaymentViewWidgetFactory(private val messenger: BinaryMessenger) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, id: Int, args: Any?): PlatformView {
return KlarnaPaymentViewWidget(context = context, id = id, messenger = messenger, creationParams = args as Map<String?, Any?>?)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.klarna.inapp.sdk.flutter_klarna_inapp_sdk.payment

import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView
import com.klarna.mobile.sdk.api.payments.KlarnaPaymentViewCallback
import com.klarna.mobile.sdk.api.payments.KlarnaPaymentsSDKError
import io.flutter.plugin.common.MethodChannel

internal class KlarnaPaymentSDKCallback constructor(methodChannel: MethodChannel) : KlarnaPaymentViewCallback {
private val callbackMethodChannel = methodChannel;

override fun onAuthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?, finalizedRequired: Boolean?) {
val args = mapOf("authToken" to authToken, "approved" to approved, "finalizedRequired" to finalizedRequired)
callbackMethodChannel.invokeMethod("onAuthorized", args)
}

override fun onErrorOccurred(view: KlarnaPaymentView, error: KlarnaPaymentsSDKError) {
val args = mapOf(
"message" to error.message,
"action" to error.action,
"name" to error.name,
"invalidFields" to error.invalidFields,
"isFatal" to error.isFatal
)
callbackMethodChannel.invokeMethod("onErrorOccurred", args)
}

override fun onFinalized(view: KlarnaPaymentView, approved: Boolean, authToken: String?) {
val args = mapOf("approved" to approved, "authToken" to authToken)
callbackMethodChannel.invokeMethod("onFinalized", args)
}

override fun onInitialized(view: KlarnaPaymentView) {
callbackMethodChannel.invokeMethod("onInitialized", null)
}

override fun onLoadPaymentReview(view: KlarnaPaymentView, showForm: Boolean) {
val args = mapOf("showForm" to showForm)
callbackMethodChannel.invokeMethod("onLoadPaymentReview", args)
}

override fun onLoaded(view: KlarnaPaymentView) {
callbackMethodChannel.invokeMethod("onLoaded", null)
}

override fun onReauthorized(view: KlarnaPaymentView, approved: Boolean, authToken: String?) {
val args = mapOf("approved" to approved, "authToken" to authToken)
callbackMethodChannel.invokeMethod("onReauthorized", args)
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
68 changes: 68 additions & 0 deletions examples/payments/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.klarna.inapp.sdk.flutter_klarna_inapp_sdk_example"
minSdkVersion 19
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source '../..'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
File renamed without changes.
1 change: 1 addition & 0 deletions examples/payments/android/settings_aar.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ':app'
File renamed without changes.
File renamed without changes.
31 changes: 31 additions & 0 deletions examples/payments/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
PODS:
- Flutter (1.0.0)
- flutter_klarna_inapp_sdk (0.0.1):
- Flutter
- KlarnaMobileSDK (~> 2.0.20)
- KlarnaMobileSDK (2.0.20):
- KlarnaMobileSDK/xcode-11.5-fat-basic (= 2.0.20)
- KlarnaMobileSDK/xcode-11.5-fat-basic (2.0.20)

DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_klarna_inapp_sdk (from `.symlinks/plugins/flutter_klarna_inapp_sdk/ios`)

SPEC REPOS:
trunk:
- KlarnaMobileSDK

EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_klarna_inapp_sdk:
:path: ".symlinks/plugins/flutter_klarna_inapp_sdk/ios"

SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_klarna_inapp_sdk: 751b9f9afbf3d6cd7f9afb6fe50b469d88c25ffe
KlarnaMobileSDK: 2f72b76a0650fe047fba0fd65e6782b5bacf1053

PODFILE CHECKSUM: 0ba44ad07df4ab62269dc769727cf0f12b1e453d

COCOAPODS: 1.10.1
47 changes: 47 additions & 0 deletions examples/payments/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_klarna_inapp_sdk_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>io.flutter.embedded_views_preview</key>
<true/>
</dict>
</plist>
Loading