@atomicfi/transact-capacitor 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,72 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
6
+ kotlinVersion = project.hasProperty('kotlinVersion') ? rootProject.ext.kotlinVersion : '2.1.21'
7
+ transactVersion = project.hasProperty('atomicTransactVersion') ? rootProject.ext.atomicTransactVersion : '3.15.2'
8
+ }
9
+
10
+ buildscript {
11
+ repositories {
12
+ google()
13
+ mavenCentral()
14
+ }
15
+ dependencies {
16
+ classpath 'com.android.tools.build:gradle:8.13.0'
17
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.hasProperty('kotlinVersion') ? rootProject.ext.kotlinVersion : '2.1.21'}"
18
+ }
19
+ }
20
+
21
+ apply plugin: 'com.android.library'
22
+ apply plugin: 'kotlin-android'
23
+
24
+ android {
25
+ namespace = "com.atomicfi.transact"
26
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
27
+
28
+ buildFeatures {
29
+ buildConfig true
30
+ }
31
+
32
+ defaultConfig {
33
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
34
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
35
+ versionCode 1
36
+ versionName "1.0"
37
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
38
+ buildConfigField "String", "TRANSACT_VERSION", "\"$transactVersion\""
39
+ }
40
+ buildTypes {
41
+ release {
42
+ minifyEnabled false
43
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
44
+ }
45
+ }
46
+ lintOptions {
47
+ abortOnError = false
48
+ }
49
+ compileOptions {
50
+ sourceCompatibility JavaVersion.VERSION_21
51
+ targetCompatibility JavaVersion.VERSION_21
52
+ }
53
+ kotlinOptions {
54
+ jvmTarget = '21'
55
+ }
56
+ }
57
+
58
+ repositories {
59
+ google()
60
+ mavenCentral()
61
+ }
62
+
63
+ dependencies {
64
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
65
+ implementation project(':capacitor-android')
66
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
67
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
68
+ implementation "financial.atomic:transact:$transactVersion"
69
+ testImplementation "junit:junit:$junitVersion"
70
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
71
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
72
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,274 @@
1
+ package com.atomicfi.transact
2
+
3
+ import android.os.Build
4
+ import android.util.Base64
5
+ import com.getcapacitor.JSObject
6
+ import com.getcapacitor.Plugin
7
+ import com.getcapacitor.PluginCall
8
+ import com.getcapacitor.PluginMethod
9
+ import com.getcapacitor.annotation.CapacitorPlugin
10
+ import financial.atomic.transact.ActionConfig
11
+ import financial.atomic.transact.Config
12
+ import financial.atomic.transact.Transact
13
+ import financial.atomic.transact.receiver.TransactBroadcastReceiver
14
+ import org.json.JSONObject
15
+
16
+ @CapacitorPlugin(name = "TransactPlugin")
17
+ class TransactPluginPlugin : Plugin() {
18
+
19
+ private var savedCall: PluginCall? = null
20
+
21
+ private fun parseEnvironmentURL(environmentObj: JSONObject?): String {
22
+ if (environmentObj == null) return "https://transact.atomicfi.com"
23
+
24
+ return when (environmentObj.optString("environment", "production")) {
25
+ "sandbox" -> "https://transact-sandbox.atomicfi.com"
26
+ "custom" -> environmentObj.optString("transactPath", "https://transact.atomicfi.com")
27
+ else -> "https://transact.atomicfi.com"
28
+ }
29
+ }
30
+
31
+ private fun parseActionEnvironment(environmentObj: JSONObject?): Pair<Config.Environment, String?> {
32
+ if (environmentObj == null) return Pair(Config.Environment.PRODUCTION, null)
33
+
34
+ return when (environmentObj.optString("environment", "production")) {
35
+ "sandbox" -> Pair(Config.Environment.SANDBOX, null)
36
+ "custom" -> {
37
+ val transactPath = environmentObj.optString("transactPath", "https://transact.atomicfi.com")
38
+ Pair(Config.Environment.CUSTOM, transactPath)
39
+ }
40
+ else -> Pair(Config.Environment.PRODUCTION, null)
41
+ }
42
+ }
43
+
44
+ @PluginMethod
45
+ fun presentTransact(call: PluginCall) {
46
+ val configObj = call.getObject("config")
47
+ if (configObj == null) {
48
+ call.reject("Config is required")
49
+ return
50
+ }
51
+
52
+ val environmentObj = call.getObject("environment")
53
+ val activity = bridge.activity
54
+ if (activity == null) {
55
+ call.reject("Activity not available")
56
+ return
57
+ }
58
+
59
+ savedCall = call
60
+
61
+ // Add platform info to config
62
+ val platform = JSONObject()
63
+ platform.put("name", "android")
64
+ platform.put("systemVersion", Build.VERSION.SDK_INT.toString())
65
+ platform.put("sdkVersion", BuildConfig.TRANSACT_VERSION + "-capacitor")
66
+ configObj.put("platform", platform)
67
+
68
+ // Base64 encode the config for the token-based constructor
69
+ val token = Base64.encodeToString(
70
+ configObj.toString().toByteArray(Charsets.UTF_8),
71
+ Base64.NO_WRAP
72
+ )
73
+
74
+ val environmentURL = parseEnvironmentURL(environmentObj)
75
+
76
+ val config = Config(
77
+ token = token,
78
+ environment = "CUSTOM",
79
+ environmentURL = environmentURL
80
+ )
81
+
82
+ activity.runOnUiThread {
83
+ try {
84
+ Transact.present(activity, config, object : TransactBroadcastReceiver() {
85
+ override fun onClose(data: JSONObject) {
86
+ notifyListeners("onClose", jsonToJSObject(data))
87
+
88
+ val result = JSObject()
89
+ result.put("closed", jsonToJSObject(data))
90
+ savedCall?.resolve(result)
91
+ savedCall = null
92
+ }
93
+
94
+ override fun onFinish(data: JSONObject) {
95
+ notifyListeners("onFinish", jsonToJSObject(data))
96
+
97
+ val result = JSObject()
98
+ result.put("finished", jsonToJSObject(data))
99
+ savedCall?.resolve(result)
100
+ savedCall = null
101
+ }
102
+
103
+ override fun onInteraction(data: JSONObject) {
104
+ notifyListeners("onInteraction", jsonToJSObject(data))
105
+ }
106
+
107
+ override fun onDataRequest(data: JSONObject) {
108
+ notifyListeners("onDataRequest", jsonToJSObject(data))
109
+ }
110
+
111
+ override fun onAuthStatusUpdate(data: JSONObject) {
112
+ notifyListeners("onAuthStatusUpdate", jsonToJSObject(data))
113
+ }
114
+
115
+ override fun onTaskStatusUpdate(data: JSONObject) {
116
+ notifyListeners("onTaskStatusUpdate", jsonToJSObject(data))
117
+ }
118
+ })
119
+ } catch (e: Exception) {
120
+ call.reject("Failed to present Transact", e)
121
+ savedCall = null
122
+ }
123
+ }
124
+ }
125
+
126
+ @PluginMethod
127
+ fun presentAction(call: PluginCall) {
128
+ val id = call.getString("id")
129
+ if (id == null) {
130
+ call.reject("id is required")
131
+ return
132
+ }
133
+
134
+ val environmentObj = call.getObject("environment")
135
+ val activity = bridge.activity
136
+ if (activity == null) {
137
+ call.reject("Activity not available")
138
+ return
139
+ }
140
+
141
+ savedCall = call
142
+
143
+ val (env, envURL) = parseActionEnvironment(environmentObj)
144
+
145
+ val config = ActionConfig(
146
+ id = id,
147
+ environment = env,
148
+ environmentURL = envURL
149
+ )
150
+
151
+ activity.runOnUiThread {
152
+ try {
153
+ Transact.presentAction(activity, config)
154
+
155
+ Transact.registerReceiver(activity, object : TransactBroadcastReceiver() {
156
+ override fun onLaunch() {
157
+ notifyListeners("onLaunch", JSObject())
158
+ }
159
+
160
+ override fun onClose(data: JSONObject) {
161
+ notifyListeners("onClose", jsonToJSObject(data))
162
+
163
+ val result = JSObject()
164
+ result.put("closed", jsonToJSObject(data))
165
+ savedCall?.resolve(result)
166
+ savedCall = null
167
+ }
168
+
169
+ override fun onFinish(data: JSONObject) {
170
+ notifyListeners("onFinish", jsonToJSObject(data))
171
+
172
+ val result = JSObject()
173
+ result.put("finished", jsonToJSObject(data))
174
+ savedCall?.resolve(result)
175
+ savedCall = null
176
+ }
177
+
178
+ override fun onAuthStatusUpdate(data: JSONObject) {
179
+ notifyListeners("onAuthStatusUpdate", jsonToJSObject(data))
180
+ }
181
+
182
+ override fun onTaskStatusUpdate(data: JSONObject) {
183
+ notifyListeners("onTaskStatusUpdate", jsonToJSObject(data))
184
+ }
185
+ })
186
+ } catch (e: Exception) {
187
+ call.reject("Failed to present action", e)
188
+ savedCall = null
189
+ }
190
+ }
191
+ }
192
+
193
+ @PluginMethod
194
+ fun hideTransact(call: PluginCall) {
195
+ val activity = bridge.activity
196
+ if (activity == null) {
197
+ call.reject("Activity not available")
198
+ return
199
+ }
200
+
201
+ activity.runOnUiThread {
202
+ try {
203
+ Transact.hideTransact(activity)
204
+ call.resolve()
205
+ } catch (e: Exception) {
206
+ call.reject("Failed to hide Transact", e)
207
+ }
208
+ }
209
+ }
210
+
211
+ @PluginMethod
212
+ fun resolveDataRequest(call: PluginCall) {
213
+ val activity = bridge.activity
214
+ if (activity == null) {
215
+ call.reject("Activity not available")
216
+ return
217
+ }
218
+
219
+ val cardObj = call.getObject("card")
220
+ val identityObj = call.getObject("identity")
221
+
222
+ var card: Config.TransactDataResponse.CardData? = null
223
+ if (cardObj != null) {
224
+ val number = cardObj.getString("number")
225
+ if (number == null) {
226
+ call.reject("Card number is required")
227
+ return
228
+ }
229
+ card = Config.TransactDataResponse.CardData(
230
+ number = number,
231
+ expiry = cardObj.optStringOrNull("expiry"),
232
+ cvv = cardObj.optStringOrNull("cvv")
233
+ )
234
+ }
235
+
236
+ var identity: Config.TransactDataResponse.Identity? = null
237
+ if (identityObj != null) {
238
+ identity = Config.TransactDataResponse.Identity(
239
+ firstName = identityObj.optStringOrNull("firstName"),
240
+ lastName = identityObj.optStringOrNull("lastName"),
241
+ postalCode = identityObj.optStringOrNull("postalCode"),
242
+ address = identityObj.optStringOrNull("address"),
243
+ address2 = identityObj.optStringOrNull("address2"),
244
+ city = identityObj.optStringOrNull("city"),
245
+ state = identityObj.optStringOrNull("state"),
246
+ phone = identityObj.optStringOrNull("phone"),
247
+ email = identityObj.optStringOrNull("email")
248
+ )
249
+ }
250
+
251
+ val response = Config.TransactDataResponse(card = card, identity = identity)
252
+
253
+ activity.runOnUiThread {
254
+ try {
255
+ Transact.sendData(activity, response)
256
+ call.resolve()
257
+ } catch (e: Exception) {
258
+ call.reject("Failed to send data response", e)
259
+ }
260
+ }
261
+ }
262
+
263
+ private fun jsonToJSObject(json: JSONObject): JSObject {
264
+ return try {
265
+ JSObject(json.toString())
266
+ } catch (e: Exception) {
267
+ JSObject()
268
+ }
269
+ }
270
+
271
+ private fun JSONObject.optStringOrNull(key: String): String? {
272
+ return if (has(key) && !isNull(key)) getString(key) else null
273
+ }
274
+ }
File without changes