@capacitor-community/stripe-terminal 6.4.0 → 6.4.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,205 @@
1
+ package com.getcapacitor.community.stripe.terminal
2
+
3
+ import android.Manifest
4
+ import android.os.Build
5
+ import android.util.Log
6
+ import androidx.annotation.RequiresApi
7
+ import com.getcapacitor.JSObject
8
+ import com.getcapacitor.PermissionState
9
+ import com.getcapacitor.Plugin
10
+ import com.getcapacitor.PluginCall
11
+ import com.getcapacitor.PluginMethod
12
+ import com.getcapacitor.annotation.CapacitorPlugin
13
+ import com.getcapacitor.annotation.Permission
14
+ import com.getcapacitor.annotation.PermissionCallback
15
+ import com.stripe.stripeterminal.external.models.TerminalException
16
+
17
+ @RequiresApi(api = Build.VERSION_CODES.S)
18
+ @CapacitorPlugin(
19
+ name = "StripeTerminal",
20
+ permissions = [Permission(
21
+ alias = "location",
22
+ strings = [Manifest.permission.ACCESS_FINE_LOCATION]
23
+ ), Permission(
24
+ alias = "bluetooth_old",
25
+ strings = [Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN]
26
+ ), Permission(
27
+ alias = "bluetooth",
28
+ strings = [Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE]
29
+ )]
30
+ )
31
+ class StripeTerminalPlugin : Plugin() {
32
+ private val implementation = StripeTerminal(
33
+ { this.context },
34
+ { this.activity },
35
+ { eventName: String?, data: JSObject? -> this.notifyListeners(eventName, data) },
36
+ logTag
37
+ )
38
+
39
+ @PluginMethod
40
+ @Throws(TerminalException::class)
41
+ fun initialize(call: PluginCall) {
42
+ this._initialize(call)
43
+ }
44
+
45
+ @PluginMethod
46
+ fun setConnectionToken(call: PluginCall) {
47
+ implementation.setConnectionToken(call)
48
+ }
49
+
50
+ @PluginMethod
51
+ fun setSimulatorConfiguration(call: PluginCall) {
52
+ implementation.setSimulatorConfiguration(call)
53
+ }
54
+
55
+ @PermissionCallback
56
+ @Throws(TerminalException::class)
57
+ private fun locationPermsCallback(call: PluginCall) {
58
+ if (getPermissionState("location") == PermissionState.GRANTED) {
59
+ this._initialize(call)
60
+ } else {
61
+ requestPermissionForAlias("location", call, "locationPermsCallback")
62
+ }
63
+ }
64
+
65
+ @PermissionCallback
66
+ @Throws(TerminalException::class)
67
+ private fun bluetoothOldPermsCallback(call: PluginCall) {
68
+ if (getPermissionState("bluetooth_old") == PermissionState.GRANTED) {
69
+ if (call.methodName == "discoverReaders") {
70
+ this.discoverReaders(call)
71
+ } else {
72
+ this.connectReader(call)
73
+ }
74
+ } else {
75
+ requestPermissionForAlias("bluetooth_old", call, "bluetoothOldPermsCallback")
76
+ }
77
+ }
78
+
79
+ @PermissionCallback
80
+ @Throws(TerminalException::class)
81
+ private fun bluetoothPermsCallback(call: PluginCall) {
82
+ if (getPermissionState("bluetooth") == PermissionState.GRANTED) {
83
+ if (call.methodName == "discoverReaders") {
84
+ this.discoverReaders(call)
85
+ } else {
86
+ this.connectReader(call)
87
+ }
88
+ } else {
89
+ requestPermissionForAlias("bluetooth", call, "bluetoothPermsCallback")
90
+ }
91
+ }
92
+
93
+ @Throws(TerminalException::class)
94
+ private fun _initialize(call: PluginCall) {
95
+ if (getPermissionState("location") != PermissionState.GRANTED) {
96
+ requestPermissionForAlias("location", call, "locationPermsCallback")
97
+ } else {
98
+ Log.d("Capacitor:permission location", getPermissionState("location").toString())
99
+ implementation.initialize(call)
100
+ }
101
+ }
102
+
103
+ @PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
104
+ fun discoverReaders(call: PluginCall) {
105
+ if (call.getString("type") == TerminalConnectTypes.Bluetooth.webEventName || call.getString(
106
+ "type"
107
+ ) == TerminalConnectTypes.Simulated.webEventName
108
+ ) {
109
+ Log.d(
110
+ "Capacitor:permission bluetooth_old",
111
+ getPermissionState("bluetooth_old").toString()
112
+ )
113
+ Log.d("Capacitor:permission bluetooth", getPermissionState("bluetooth").toString())
114
+ if (Build.VERSION.SDK_INT <= 30 && getPermissionState("bluetooth_old") != PermissionState.GRANTED) {
115
+ requestPermissionForAlias("bluetooth_old", call, "bluetoothOldPermsCallback")
116
+ } else if (Build.VERSION.SDK_INT > 30 && getPermissionState("bluetooth") != PermissionState.GRANTED) {
117
+ requestPermissionForAlias("bluetooth", call, "bluetoothPermsCallback")
118
+ } else {
119
+ implementation.onDiscoverReaders(call)
120
+ }
121
+ } else {
122
+ implementation.onDiscoverReaders(call)
123
+ }
124
+ }
125
+
126
+ @PluginMethod
127
+ fun cancelDiscoverReaders(call: PluginCall) {
128
+ implementation.cancelDiscoverReaders(call)
129
+ }
130
+
131
+ @PluginMethod
132
+ fun connectReader(call: PluginCall) {
133
+ if (call.getString("type") == TerminalConnectTypes.Bluetooth.webEventName) {
134
+ Log.d(
135
+ "Capacitor:permission bluetooth_old",
136
+ getPermissionState("bluetooth_old").toString()
137
+ )
138
+ Log.d("Capacitor:permission bluetooth", getPermissionState("bluetooth").toString())
139
+ if (Build.VERSION.SDK_INT <= 30 && getPermissionState("bluetooth_old") != PermissionState.GRANTED) {
140
+ requestPermissionForAlias("bluetooth_old", call, "bluetoothOldPermsCallback")
141
+ } else if (Build.VERSION.SDK_INT > 30 && getPermissionState("bluetooth") != PermissionState.GRANTED) {
142
+ requestPermissionForAlias("bluetooth", call, "bluetoothPermsCallback")
143
+ } else {
144
+ implementation.connectReader(call)
145
+ }
146
+ } else {
147
+ implementation.connectReader(call)
148
+ }
149
+ }
150
+
151
+ @PluginMethod
152
+ fun getConnectedReader(call: PluginCall) {
153
+ implementation.getConnectedReader(call)
154
+ }
155
+
156
+ @PluginMethod
157
+ fun disconnectReader(call: PluginCall) {
158
+ implementation.disconnectReader(call)
159
+ }
160
+
161
+ @PluginMethod
162
+ fun collectPaymentMethod(call: PluginCall) {
163
+ implementation.collectPaymentMethod(call)
164
+ }
165
+
166
+ @PluginMethod
167
+ fun cancelCollectPaymentMethod(call: PluginCall) {
168
+ implementation.cancelCollectPaymentMethod(call)
169
+ }
170
+
171
+ @PluginMethod
172
+ fun confirmPaymentIntent(call: PluginCall) {
173
+ implementation.confirmPaymentIntent(call)
174
+ }
175
+
176
+ @PluginMethod
177
+ fun installAvailableUpdate(call: PluginCall) {
178
+ implementation.installAvailableUpdate(call)
179
+ }
180
+
181
+ @PluginMethod
182
+ fun cancelInstallUpdate(call: PluginCall) {
183
+ implementation.cancelInstallUpdate(call)
184
+ }
185
+
186
+ @PluginMethod
187
+ fun setReaderDisplay(call: PluginCall) {
188
+ implementation.setReaderDisplay(call)
189
+ }
190
+
191
+ @PluginMethod
192
+ fun clearReaderDisplay(call: PluginCall) {
193
+ implementation.clearReaderDisplay(call)
194
+ }
195
+
196
+ @PluginMethod
197
+ fun rebootReader(call: PluginCall) {
198
+ implementation.rebootReader(call)
199
+ }
200
+
201
+ @PluginMethod
202
+ fun cancelReaderReconnection(call: PluginCall) {
203
+ implementation.cancelReaderReconnection(call)
204
+ }
205
+ }
@@ -0,0 +1,85 @@
1
+ package com.getcapacitor.community.stripe.terminal
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import androidx.core.util.Supplier
6
+ import com.android.volley.Response
7
+ import com.android.volley.toolbox.StringRequest
8
+ import com.android.volley.toolbox.Volley
9
+ import com.getcapacitor.JSObject
10
+ import com.getcapacitor.PluginCall
11
+ import com.google.android.gms.common.util.BiConsumer
12
+ import com.stripe.stripeterminal.external.callable.ConnectionTokenCallback
13
+ import com.stripe.stripeterminal.external.callable.ConnectionTokenProvider
14
+ import com.stripe.stripeterminal.external.models.ConnectionTokenException
15
+ import org.json.JSONException
16
+ import org.json.JSONObject
17
+ import java.util.Objects
18
+
19
+ class TokenProvider(
20
+ protected var contextSupplier: Supplier<Context>,
21
+ protected val tokenProviderEndpoint: String,
22
+ protected var notifyListenersFunction: BiConsumer<String, JSObject>
23
+ ) : ConnectionTokenProvider {
24
+ private var pendingCallback: ArrayList<ConnectionTokenCallback> = ArrayList()
25
+
26
+ fun setConnectionToken(call: PluginCall) {
27
+ val token = call.getString("token", "")
28
+ if (pendingCallback.isNotEmpty()) {
29
+ val pending = pendingCallback.removeAt(0)
30
+ if (token == "") {
31
+ pending.onFailure(ConnectionTokenException("Missing `token` is empty"))
32
+ call.reject("Missing `token` is empty")
33
+ } else {
34
+ pending.onSuccess(token!!)
35
+ call.resolve()
36
+ }
37
+ } else {
38
+ call.reject("Stripe Terminal do not pending fetchConnectionToken")
39
+ }
40
+ }
41
+
42
+ override fun fetchConnectionToken(callback: ConnectionTokenCallback) {
43
+ if (this.tokenProviderEndpoint == "") {
44
+ pendingCallback.add(callback)
45
+ this.notifyListeners(
46
+ TerminalEnumEvent.RequestedConnectionToken.webEventName,
47
+ JSObject()
48
+ )
49
+ } else {
50
+ try {
51
+ val queue = Volley.newRequestQueue(contextSupplier.get())
52
+ val postRequest: StringRequest = object : StringRequest(
53
+ Method.POST,
54
+ this.tokenProviderEndpoint,
55
+ Response.Listener { response ->
56
+ try {
57
+ val jsonObject = JSONObject(response)
58
+ Log.d("TokenProvider", jsonObject.getString("secret"))
59
+ callback.onSuccess(jsonObject.getString("secret"))
60
+ } catch (e: JSONException) {
61
+ callback.onFailure(ConnectionTokenException(Objects.requireNonNull(e.localizedMessage)))
62
+ throw RuntimeException(e)
63
+ }
64
+ },
65
+ Response.ErrorListener { e -> throw RuntimeException(e) }
66
+ ) {
67
+ // @Override
68
+ // protected Map<String,String> getParams(){
69
+ // Map<String,String> params = new HashMap<>();
70
+ // params.put("word","test");
71
+ // return params;
72
+ // }
73
+ }
74
+
75
+ queue.add(postRequest)
76
+ } catch (e: Exception) {
77
+ callback.onFailure(ConnectionTokenException("Failed to fetch connection token", e))
78
+ }
79
+ }
80
+ }
81
+
82
+ protected fun notifyListeners(eventName: String?, data: JSObject?) {
83
+ notifyListenersFunction.accept(eventName!!, data!!)
84
+ }
85
+ }
@@ -0,0 +1,24 @@
1
+ package com.getcapacitor.community.stripe.terminal.helper
2
+
3
+ import android.content.Context
4
+ import android.content.pm.PackageManager
5
+ import androidx.core.util.Supplier
6
+ import com.getcapacitor.Logger
7
+
8
+ class MetaData(protected var contextSupplier: Supplier<Context>) {
9
+ var enableIdentifier: Boolean = false
10
+
11
+ init {
12
+ try {
13
+ val appInfo = contextSupplier
14
+ .get()
15
+ .packageManager
16
+ .getApplicationInfo(contextSupplier.get().packageName, PackageManager.GET_META_DATA)
17
+
18
+ enableIdentifier =
19
+ appInfo.metaData.getBoolean("com.getcapacitor.community.stripe.enableIdentifier")
20
+ } catch (ignored: Exception) {
21
+ Logger.info("MetaData didn't be prepare fore Google Pay.")
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,90 @@
1
+ package com.getcapacitor.community.stripe.terminal.helper
2
+
3
+ import com.getcapacitor.JSObject
4
+ import com.stripe.stripeterminal.external.models.DeviceType
5
+ import com.stripe.stripeterminal.external.models.Location
6
+ import com.stripe.stripeterminal.external.models.LocationStatus
7
+ import com.stripe.stripeterminal.external.models.Reader
8
+ import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate
9
+
10
+ class TerminalMappers {
11
+ fun mapFromLocation(location: Location?): JSObject {
12
+ if (location == null) {
13
+ return JSObject()
14
+ }
15
+
16
+ val address = JSObject()
17
+
18
+ if (location.address != null) {
19
+ address
20
+ .put("country", location.address!!.country)
21
+ .put("city", location.address!!.city)
22
+ .put("postalCode", location.address!!.postalCode)
23
+ .put("line1", location.address!!.line1)
24
+ .put("line2", location.address!!.line2)
25
+ .put("state", location.address!!.state)
26
+ }
27
+
28
+ return JSObject()
29
+ .put("id", location.id)
30
+ .put("displayName", location.displayName)
31
+ .put("address", address)
32
+ .put("livemode", location.livemode)
33
+ }
34
+
35
+ fun mapFromReaderSoftwareUpdate(update: ReaderSoftwareUpdate?): JSObject {
36
+ if (update == null) {
37
+ return JSObject()
38
+ }
39
+
40
+ return JSObject()
41
+ .put("deviceSoftwareVersion", update.version)
42
+ .put("estimatedUpdateTime", update.durationEstimate.toString())
43
+ .put("requiredAt", update.requiredAtMs)
44
+ }
45
+
46
+ fun mapFromLocationStatus(status: LocationStatus?): String {
47
+ if (status == null) {
48
+ return "UNKNOWN"
49
+ }
50
+
51
+ return when (status) {
52
+ LocationStatus.NOT_SET -> "NOT_SET"
53
+ LocationStatus.SET -> "SET"
54
+ LocationStatus.UNKNOWN -> "UNKNOWN"
55
+ else -> "UNKNOWN"
56
+ }
57
+ }
58
+
59
+ fun mapFromNetworkStatus(status: Reader.NetworkStatus?): String {
60
+ if (status == null) {
61
+ return "UNKNOWN"
62
+ }
63
+
64
+ return when (status) {
65
+ Reader.NetworkStatus.OFFLINE -> "OFFLINE"
66
+ Reader.NetworkStatus.ONLINE -> "ONLINE"
67
+ else -> "UNKNOWN"
68
+ }
69
+ }
70
+
71
+ fun mapFromDeviceType(type: DeviceType): String {
72
+ return when (type) {
73
+ DeviceType.CHIPPER_1X -> "chipper1X"
74
+ DeviceType.CHIPPER_2X -> "chipper2X"
75
+ DeviceType.TAP_TO_PAY_DEVICE -> "tapToPayDevice"
76
+ DeviceType.ETNA -> "etna"
77
+ DeviceType.STRIPE_M2 -> "stripeM2"
78
+ DeviceType.STRIPE_S700 -> "stripeS700"
79
+ DeviceType.STRIPE_S700_DEVKIT -> "stripeS700Devkit"
80
+ DeviceType.UNKNOWN -> "unknown"
81
+ DeviceType.VERIFONE_P400 -> "verifoneP400"
82
+ DeviceType.WISECUBE -> "wiseCube"
83
+ DeviceType.WISEPAD_3 -> "wisePad3"
84
+ DeviceType.WISEPAD_3S -> "wisePad3s"
85
+ DeviceType.WISEPOS_E -> "wisePosE"
86
+ DeviceType.WISEPOS_E_DEVKIT -> "wisePosEDevkit"
87
+ else -> throw IllegalArgumentException("Unknown DeviceType: $type")
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,22 @@
1
+ package com.getcapacitor.community.stripe.terminal.models
2
+
3
+ import android.app.Activity
4
+ import android.content.Context
5
+ import androidx.core.util.Supplier
6
+ import com.getcapacitor.JSObject
7
+ import com.google.android.gms.common.util.BiConsumer
8
+
9
+ abstract class Executor(
10
+ protected var contextSupplier: Supplier<Context>,
11
+ protected val activitySupplier: Supplier<Activity>,
12
+ protected var notifyListenersFunction: BiConsumer<String, JSObject>,
13
+ pluginLogTag: String,
14
+ executorTag: String
15
+ ) {
16
+ protected val logTag: String = "$pluginLogTag|$executorTag"
17
+
18
+ // Eventually we can change the notification directly here!
19
+ protected fun notifyListeners(eventName: String, data: JSObject) {
20
+ notifyListenersFunction.accept(eventName, data)
21
+ }
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor-community/stripe-terminal",
3
- "version": "6.4.0",
3
+ "version": "6.4.1",
4
4
  "engines": {
5
5
  "node": ">=18.0.0"
6
6
  },