Skip to content

Commit

Permalink
Merge pull request #7 from xendit/add_ios_fingerprint_sdk
Browse files Browse the repository at this point in the history
Add iOS FingerprintSDK
  • Loading branch information
ahmadAlfhajri authored Dec 12, 2024
2 parents a655fc9 + 9bb6b62 commit 5828167
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.cards.session.android

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun CustomTextField(
label: String,
placeholder: String = "",
onValueChange: (String) -> Unit
) {
var text by remember { mutableStateOf("") }

Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
OutlinedTextField(
value = text,
onValueChange = { newValue ->
text = newValue
onValueChange(newValue)
},
label = { Text(text = label) },
placeholder = { Text(text = placeholder) },
modifier = Modifier.fillMaxWidth()
)
}
}
20 changes: 17 additions & 3 deletions androidApp/src/main/java/com/cards/session/android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ fun AppRoot() {
}
val state by cardSessions.state.collectAsState()
val scope = CoroutineScope(Dispatchers.Main)
var paymentSessionId = ""

NavHost(
navController = navController,
Expand All @@ -78,6 +79,19 @@ fun AppRoot() {
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)

Spacer(modifier = Modifier.height(16.dp))

CustomTextField(
label = "Enter paymentSessionId",
placeholder = "paymentSessionId",
onValueChange = { newText ->
// Handle text change here
paymentSessionId = newText
println("New text: $newText")
}
)

Spacer(modifier = Modifier.height(16.dp))
Button(
content = { Text(text = "Collect Card Data") },
Expand All @@ -91,8 +105,8 @@ fun AppRoot() {
cardholderFirstName = "First",
cardholderLastName = "Name",
cardholderEmail = "[email protected]",
cardholderPhoneNumber = "01231245242",
paymentSessionId = "ps-1234567890abcdef12345678"
cardholderPhoneNumber = "+123456789",
paymentSessionId = paymentSessionId
)
}
}
Expand All @@ -104,7 +118,7 @@ fun AppRoot() {
scope.launch {
cardSessions.collectCvn(
cvn = "123",
paymentSessionId = "ps-1234567890abcdef12345678"
paymentSessionId = paymentSessionId
)
}
}
Expand Down
31 changes: 30 additions & 1 deletion cardsSdk/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework

plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.native.cocoapods)
Expand All @@ -10,16 +12,43 @@ kotlin {
iosArm64()
iosSimulatorArm64()

val xcframeworkName = "cardSdk"
val xcFrameworkVersion = "1.0.0"
val xcFrameworkBundleVersion = "1" // Increase it everytime version changed
val xcf = XCFramework(xcframeworkName)

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64(),
).forEach {
it.binaries.framework {
baseName = xcframeworkName

// Specify CFBundleIdentifier to uniquely identify the framework
binaryOption("bundleId", "com.cards.session.${xcframeworkName}")
binaryOption("bundleShortVersionString", xcFrameworkVersion)
binaryOption("bundleVersion", xcFrameworkBundleVersion)
xcf.add(this)
isStatic = true
}
}

cocoapods {
summary = "Cards Session SDK module"
homepage = "Link to the Cards Session Module homepage"
version = "1.0"
ios.deploymentTarget = "16.0"
ios.deploymentTarget = "14.0"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "cardsSdk"
isStatic = true
}

pod("XenditFingerprintSDK") {
version = "1.0.1"
extraOpts += listOf("-compiler-option", "-fmodules")
}
}

sourceSets {
Expand Down
4 changes: 2 additions & 2 deletions cardsSdk/cardsSdk.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Pod::Spec.new do |spec|
spec.summary = 'Cards Session SDK module'
spec.vendored_frameworks = 'build/cocoapods/framework/cardsSdk.framework'
spec.libraries = 'c++'
spec.ios.deployment_target = '16.0'
spec.ios.deployment_target = '14.0'
spec.dependency 'XenditFingerprintSDK', '1.0.1'

if !Dir.exist?('build/cocoapods/framework/cardsSdk.framework') || Dir.empty?('build/cocoapods/framework/cardsSdk.framework')
raise "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ package com.cards.session.cards.sdk

actual fun CardSessions.Factory.create(apiKey: String): CardSessions {
return CardSessionsImpl.create(apiKey)
}
}

fun CardSessions.Factory.create(apiKey: String, isEnableLog: Boolean): CardSessions {
return CardSessionsImpl.create(apiKey, isEnableLog)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.cards.session.cards.sdk

import cocoapods.XenditFingerprintSDK.FingerprintSDK
import cocoapods.XenditFingerprintSDK.LogModeAll
import com.cards.session.cards.models.CardsRequestDto
import com.cards.session.cards.models.CardsResponseDto
import com.cards.session.cards.models.DeviceFingerprint
Expand All @@ -12,15 +14,18 @@ import com.cards.session.util.AuthTokenGenerator
import com.cards.session.util.Logger
import com.cardsession.sdk.CreditCardUtil
import io.ktor.client.HttpClient
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import platform.Foundation.NSLog

internal class CardSessionsImpl private constructor(
internal class CardSessionsImpl @OptIn(ExperimentalForeignApi::class)
private constructor(
private val apiKey: String,
private val httpClient: HttpClient
private val httpClient: HttpClient,
private val fingerprintSDK: FingerprintSDK
) : CardSessions {
private val TAG = "CardSessionsImpl"
private val logger = Logger(TAG)
Expand Down Expand Up @@ -129,17 +134,40 @@ internal class CardSessionsImpl private constructor(
}
}

@OptIn(ExperimentalForeignApi::class)
private fun getFingerprint(eventName: String): String {
// TODO: Implement iOS-specific device fingerprinting
return ""
fingerprintSDK.scanWithEvent_name(
event_name = eventName,
event_id = eventName,
completion = { response, errorMsg ->
if (errorMsg != null) {
logger.e("Scan failed for event: $eventName, error: $errorMsg")
}
}
)

return fingerprintSDK.getSessionId()
}

companion object {
fun create(apiKey: String): CardSessions {
Logger("").debugBuild()
@OptIn(ExperimentalForeignApi::class)
fun create(apiKey: String, isEnableLog: Boolean = false): CardSessions {
val fingerprint = FingerprintSDK()

if (isEnableLog) {
Logger("").debugBuild()
}

try {
fingerprint.initSDKWithApiKey(apiKey)
} catch (e: Exception) {
// Logger("CardSessions").e( "Failed to initialize XenditFingerprintSDK", e)
}

return CardSessionsImpl(
apiKey = apiKey,
httpClient = HttpClientFactory().create()
httpClient = HttpClientFactory().create(),
fingerprintSDK = fingerprint
)
}
}
Expand Down
6 changes: 3 additions & 3 deletions cortex.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
openapi: 3.0.1
info:
title: xendit-cards-sdk
title: cards-session-mobile-sdk
description:
x-cortex-git:
github:
repository: xendit/xendit-cards-sdk
x-cortex-tag: xendit-cards-sdk
repository: xendit/cards-session-mobile-sdk
x-cortex-tag: cards-session-mobile-sdk
x-cortex-dependency: []
x-cortex-service-groups:
- P2
Expand Down
11 changes: 9 additions & 2 deletions iosApp/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
PODS:
- cardsSdk (1.0)
- cardsSdk (1.0):
- XenditFingerprintSDK (= 1.0.1)
- XenditFingerprintSDK (1.0.1)

DEPENDENCIES:
- cardsSdk (from `../cardsSdk`)

SPEC REPOS:
trunk:
- XenditFingerprintSDK

EXTERNAL SOURCES:
cardsSdk:
:path: "../cardsSdk"

SPEC CHECKSUMS:
cardsSdk: 7f311fe8287c75352cb28bd092ef18f02b56f338
cardsSdk: 9e0b4e91658434b731daf4d2262393018fe4f742
XenditFingerprintSDK: 29410a2dcf467fe33d6e0167f590deae47c753ee

PODFILE CHECKSUM: 2d3ff3b1724835dab0bcce0b112c67a9f1440453

Expand Down
24 changes: 23 additions & 1 deletion iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand All @@ -12,6 +12,7 @@
0C0CDBC02D06AD03002DC16A /* CardSessionsImpl.kt in Resources */ = {isa = PBXBuildFile; fileRef = 0C0CDBBE2D06AD03002DC16A /* CardSessionsImpl.kt */; };
0C0CDBC62D06DB5C002DC16A /* CardSessions.kt in Resources */ = {isa = PBXBuildFile; fileRef = 0C0CDBC52D06DB5C002DC16A /* CardSessions.kt */; };
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };
21FA6F202D0997E600DD5E13 /* CustomTextFieldStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FA6F1F2D0997E600DD5E13 /* CustomTextFieldStyle.swift */; };
2F9A03F732FC062E0B94E281 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E47D7C75F016D7EF416763 /* Pods_iosApp.framework */; };
7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
/* End PBXBuildFile section */
Expand All @@ -22,6 +23,7 @@
0C0CDBBE2D06AD03002DC16A /* CardSessionsImpl.kt */ = {isa = PBXFileReference; lastKnownFileType = text; name = CardSessionsImpl.kt; path = ../cardsSdk/src/iosMain/kotlin/com/cards/session/cards/sdk/CardSessionsImpl.kt; sourceTree = SOURCE_ROOT; };
0C0CDBC52D06DB5C002DC16A /* CardSessions.kt */ = {isa = PBXFileReference; lastKnownFileType = text; name = CardSessions.kt; path = ../cardsSdk/src/commonMain/kotlin/com/cards/session/cards/sdk/CardSessions.kt; sourceTree = SOURCE_ROOT; };
2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = "<group>"; };
21FA6F1F2D0997E600DD5E13 /* CustomTextFieldStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextFieldStyle.swift; sourceTree = "<group>"; };
42AF08E65F4330F0220806A5 /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = "<group>"; };
7555FF7B242A565900829871 /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -75,6 +77,7 @@
0C0CDBBE2D06AD03002DC16A /* CardSessionsImpl.kt */,
058557BA273AAA24004C7B11 /* Assets.xcassets */,
7555FF82242A565900829871 /* ContentView.swift */,
21FA6F1F2D0997E600DD5E13 /* CustomTextFieldStyle.swift */,
7555FF8C242A565B00829871 /* Info.plist */,
2152FB032600AC8F00CF470E /* iOSApp.swift */,
058557D7273AAEEB004C7B11 /* Preview Content */,
Expand Down Expand Up @@ -110,6 +113,7 @@
7555FF77242A565900829871 /* Sources */,
7555FF79242A565900829871 /* Resources */,
50F90884C22C0FEF776BD342 /* Frameworks */,
0321158BB61A2C062DF08FCD /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -168,6 +172,23 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
0321158BB61A2C062DF08FCD /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
87FCF521B92BEDD427DAB3FE /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -199,6 +220,7 @@
files = (
2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,
7555FF83242A565900829871 /* ContentView.swift in Sources */,
21FA6F202D0997E600DD5E13 /* CustomTextFieldStyle.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Loading

0 comments on commit 5828167

Please sign in to comment.