@capacitor-community/stripe-terminal 5.2.0 → 5.3.0
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.
- package/CapacitorCommunityStripeTerminal.podspec +1 -1
- package/README.md +33 -4
- package/android/build.gradle +14 -8
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.java +197 -101
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java +2 -2
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TokenProvider.java +3 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/MetaData.java +2 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/models/Executor.java +2 -3
- package/ios/Plugin/StripeTerminal.swift +51 -2
- package/ios/Plugin/StripeTerminalPlugin.swift +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,11 +24,11 @@ npx cap sync
|
|
|
24
24
|
Add permissions to your `android/app/src/main/AndroidManifest.xml` file:
|
|
25
25
|
|
|
26
26
|
```diff
|
|
27
|
-
+ <uses-permission android:name="android.permission.
|
|
28
|
-
+ <uses-permission android:name="android.permission.
|
|
29
|
-
+ <uses-permission android:name="android.permission.
|
|
30
|
-
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
|
27
|
+
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
28
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
|
29
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
|
31
30
|
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
|
31
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
If used in conjunction with the `@capacitor-community/stripe` plugin, the following settings may be necessary
|
|
@@ -44,6 +44,35 @@ android {
|
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
And update minSdkVersion to 26 And compileSdkVersion to 34 in your `android/app/build.gradle` file:
|
|
48
|
+
|
|
49
|
+
```diff
|
|
50
|
+
ext {
|
|
51
|
+
- minSdkVersion = 22
|
|
52
|
+
- compileSdkVersion = 33
|
|
53
|
+
+ minSdkVersion = 26
|
|
54
|
+
+ compileSdkVersion = 34
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
(async ()=> {
|
|
61
|
+
/**
|
|
62
|
+
* tokenProviderEndpoint: The URL of your backend to provide a token. Use Post request to get a token.
|
|
63
|
+
*/
|
|
64
|
+
await StripeTerminal.initialize({ tokenProviderEndpoint: 'https://example.com/token', isTest: true })
|
|
65
|
+
const { readers } = await StripeTerminal.discoverReaders({
|
|
66
|
+
type: TerminalConnectTypes.TapToPay,
|
|
67
|
+
locationId: "**************",
|
|
68
|
+
});
|
|
69
|
+
await StripeTerminal.connectReader({
|
|
70
|
+
reader: readers[0],
|
|
71
|
+
});
|
|
72
|
+
await StripeTerminal.collect({ paymentIntent: "**************" });
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
47
76
|
## API
|
|
48
77
|
|
|
49
78
|
<docgen-index>
|
package/android/build.gradle
CHANGED
|
@@ -3,17 +3,22 @@ ext {
|
|
|
3
3
|
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
|
|
4
4
|
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
|
|
5
5
|
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
|
|
6
|
+
|
|
7
|
+
playServicesWalletVersion = project.hasProperty('playServicesWalletVersion') ? rootProject.ext.playServicesWalletVersion : '19.2.+'
|
|
8
|
+
volleyVersion = project.hasProperty('volleyVersion') ? rootProject.ext.volleyVersion : '1.2.1'
|
|
9
|
+
stripeterminalLocalmobileVersion = project.hasProperty('stripeterminalLocalmobileVersion') ? rootProject.ext.stripeterminalLocalmobileVersion : '3.0.+'
|
|
10
|
+
stripeterminalCoreVersion = project.hasProperty('stripeterminalCoreVersion') ? rootProject.ext.stripeterminalCoreVersion : '3.1.+'
|
|
6
11
|
}
|
|
7
12
|
|
|
8
13
|
buildscript {
|
|
9
|
-
ext.
|
|
14
|
+
ext.kotlinVersion = project.hasProperty("kotlinVersion") ? rootProject.ext.kotlinVersion : '1.8.20'
|
|
10
15
|
repositories {
|
|
11
16
|
google()
|
|
12
17
|
mavenCentral()
|
|
13
18
|
}
|
|
14
19
|
dependencies {
|
|
15
20
|
classpath 'com.android.tools.build:gradle:8.0.0'
|
|
16
|
-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$
|
|
21
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
24
|
|
|
@@ -62,9 +67,10 @@ dependencies {
|
|
|
62
67
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
63
68
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
64
69
|
|
|
65
|
-
implementation "
|
|
66
|
-
|
|
67
|
-
implementation
|
|
68
|
-
implementation
|
|
69
|
-
implementation "
|
|
70
|
-
|
|
70
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
|
|
71
|
+
|
|
72
|
+
implementation "com.stripe:stripeterminal-core:$stripeterminalCoreVersion"
|
|
73
|
+
implementation "com.stripe:stripeterminal-localmobile:$stripeterminalLocalmobileVersion"
|
|
74
|
+
implementation "com.android.volley:volley:$volleyVersion"
|
|
75
|
+
implementation "com.google.android.gms:play-services-wallet:$playServicesWalletVersion"
|
|
76
|
+
}
|
package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.java
CHANGED
|
@@ -5,12 +5,14 @@ import android.app.Activity;
|
|
|
5
5
|
import android.app.Application;
|
|
6
6
|
import android.bluetooth.BluetoothAdapter;
|
|
7
7
|
import android.content.Context;
|
|
8
|
-
import android.content.pm.ApplicationInfo;
|
|
9
8
|
import android.content.pm.PackageManager;
|
|
10
9
|
import android.util.Log;
|
|
10
|
+
|
|
11
11
|
import androidx.annotation.NonNull;
|
|
12
|
+
import androidx.annotation.Nullable;
|
|
12
13
|
import androidx.core.app.ActivityCompat;
|
|
13
14
|
import androidx.core.util.Supplier;
|
|
15
|
+
|
|
14
16
|
import com.getcapacitor.JSArray;
|
|
15
17
|
import com.getcapacitor.JSObject;
|
|
16
18
|
import com.getcapacitor.PluginCall;
|
|
@@ -23,20 +25,29 @@ import com.stripe.stripeterminal.external.callable.Cancelable;
|
|
|
23
25
|
import com.stripe.stripeterminal.external.callable.DiscoveryListener;
|
|
24
26
|
import com.stripe.stripeterminal.external.callable.PaymentIntentCallback;
|
|
25
27
|
import com.stripe.stripeterminal.external.callable.ReaderCallback;
|
|
28
|
+
import com.stripe.stripeterminal.external.callable.ReaderListener;
|
|
26
29
|
import com.stripe.stripeterminal.external.callable.TerminalListener;
|
|
27
|
-
import com.stripe.stripeterminal.external.models.
|
|
30
|
+
import com.stripe.stripeterminal.external.models.CardPresentDetails;
|
|
31
|
+
import com.stripe.stripeterminal.external.models.CollectConfiguration;
|
|
32
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.BluetoothConnectionConfiguration;
|
|
33
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.InternetConnectionConfiguration;
|
|
34
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.LocalMobileConnectionConfiguration;
|
|
35
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration.UsbConnectionConfiguration;
|
|
28
36
|
import com.stripe.stripeterminal.external.models.ConnectionStatus;
|
|
29
37
|
import com.stripe.stripeterminal.external.models.DiscoveryConfiguration;
|
|
30
|
-
import com.stripe.stripeterminal.external.models.DiscoveryMethod;
|
|
31
38
|
import com.stripe.stripeterminal.external.models.PaymentIntent;
|
|
39
|
+
import com.stripe.stripeterminal.external.models.PaymentMethod;
|
|
32
40
|
import com.stripe.stripeterminal.external.models.PaymentStatus;
|
|
33
41
|
import com.stripe.stripeterminal.external.models.Reader;
|
|
42
|
+
import com.stripe.stripeterminal.external.models.ReaderSoftwareUpdate;
|
|
34
43
|
import com.stripe.stripeterminal.external.models.TerminalException;
|
|
35
44
|
import com.stripe.stripeterminal.log.LogLevel;
|
|
45
|
+
|
|
46
|
+
import org.jetbrains.annotations.NotNull;
|
|
47
|
+
|
|
36
48
|
import java.util.ArrayList;
|
|
37
49
|
import java.util.List;
|
|
38
50
|
import java.util.Objects;
|
|
39
|
-
import org.json.JSONException;
|
|
40
51
|
|
|
41
52
|
public class StripeTerminal extends Executor {
|
|
42
53
|
|
|
@@ -47,17 +58,17 @@ public class StripeTerminal extends Executor {
|
|
|
47
58
|
private PluginCall collectCall;
|
|
48
59
|
private final JSObject emptyObject = new JSObject();
|
|
49
60
|
private Boolean isTest;
|
|
50
|
-
private
|
|
61
|
+
private TerminalConnectTypes terminalConnectType;
|
|
51
62
|
|
|
52
63
|
public StripeTerminal(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
Supplier<Context> contextSupplier,
|
|
65
|
+
Supplier<Activity> activitySupplier,
|
|
66
|
+
BiConsumer<String, JSObject> notifyListenersFunction,
|
|
67
|
+
String pluginLogTag
|
|
57
68
|
) {
|
|
58
69
|
super(contextSupplier, activitySupplier, notifyListenersFunction, pluginLogTag, "StripeTerminalExecutor");
|
|
59
70
|
this.contextSupplier = contextSupplier;
|
|
60
|
-
this.readers = new ArrayList
|
|
71
|
+
this.readers = new ArrayList<>();
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
public void initialize(final PluginCall call) throws TerminalException {
|
|
@@ -66,36 +77,36 @@ public class StripeTerminal extends Executor {
|
|
|
66
77
|
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
|
|
67
78
|
if (!bluetooth.isEnabled()) {
|
|
68
79
|
if (
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
ActivityCompat.checkSelfPermission(this.contextSupplier.get(), Manifest.permission.BLUETOOTH_CONNECT) ==
|
|
81
|
+
PackageManager.PERMISSION_GRANTED
|
|
71
82
|
) {
|
|
72
83
|
bluetooth.enable();
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
this.activitySupplier.get()
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
.runOnUiThread(
|
|
89
|
+
() -> {
|
|
90
|
+
TerminalApplicationDelegate.onCreate((Application) this.contextSupplier.get().getApplicationContext());
|
|
91
|
+
notifyListeners(TerminalEnumEvent.Loaded.getWebEventName(), emptyObject);
|
|
92
|
+
call.resolve();
|
|
93
|
+
}
|
|
94
|
+
);
|
|
84
95
|
TerminalListener listener = new TerminalListener() {
|
|
85
96
|
@Override
|
|
86
97
|
public void onUnexpectedReaderDisconnect(@NonNull Reader reader) {
|
|
87
98
|
// TODO: Listenerを追加
|
|
88
99
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
|
|
101
|
+
@Override
|
|
102
|
+
public void onConnectionStatusChange(@NonNull ConnectionStatus status) {
|
|
103
|
+
// TODO: Listenerを追加
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public void onPaymentStatusChange(@NonNull PaymentStatus status) {
|
|
108
|
+
// TODO: Listenerを追加
|
|
109
|
+
}
|
|
99
110
|
};
|
|
100
111
|
LogLevel logLevel = LogLevel.VERBOSE;
|
|
101
112
|
TokenProvider tokenProvider = new TokenProvider(this.contextSupplier, call.getString("tokenProviderEndpoint"));
|
|
@@ -105,18 +116,32 @@ public class StripeTerminal extends Executor {
|
|
|
105
116
|
Terminal.getInstance();
|
|
106
117
|
}
|
|
107
118
|
|
|
108
|
-
public void onDiscoverReaders(final PluginCall call)
|
|
119
|
+
public void onDiscoverReaders(final PluginCall call) {
|
|
120
|
+
if (ActivityCompat.checkSelfPermission(this.contextSupplier.get(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
|
121
|
+
Log.d(this.logTag, "android.permission.ACCESS_FINE_LOCATION permission is not granted.");
|
|
122
|
+
call.reject("android.permission.ACCESS_FINE_LOCATION permission is not granted.");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
109
126
|
this.locationId = call.getString("locationId");
|
|
127
|
+
final DiscoveryConfiguration config;
|
|
110
128
|
if (Objects.equals(call.getString("type"), TerminalConnectTypes.TapToPay.getWebEventName())) {
|
|
111
|
-
|
|
129
|
+
config = new DiscoveryConfiguration.LocalMobileDiscoveryConfiguration(this.isTest);
|
|
130
|
+
this.terminalConnectType = TerminalConnectTypes.TapToPay;
|
|
112
131
|
} else if (Objects.equals(call.getString("type"), TerminalConnectTypes.Internet.getWebEventName())) {
|
|
113
|
-
|
|
132
|
+
config = new DiscoveryConfiguration.InternetDiscoveryConfiguration(this.locationId, this.isTest);
|
|
133
|
+
this.terminalConnectType = TerminalConnectTypes.Internet;
|
|
134
|
+
} else if (Objects.equals(call.getString("type"), TerminalConnectTypes.Usb.getWebEventName())) {
|
|
135
|
+
config = new DiscoveryConfiguration.UsbDiscoveryConfiguration(0, this.isTest);
|
|
136
|
+
this.terminalConnectType = TerminalConnectTypes.Usb;
|
|
137
|
+
} else if (Objects.equals(call.getString("type"), TerminalConnectTypes.Bluetooth.getWebEventName()) || Objects.equals(call.getString("type"), TerminalConnectTypes.Simulated.getWebEventName())) {
|
|
138
|
+
config = new DiscoveryConfiguration.BluetoothDiscoveryConfiguration(0, this.isTest);
|
|
139
|
+
this.terminalConnectType = TerminalConnectTypes.Bluetooth;
|
|
114
140
|
} else {
|
|
115
141
|
call.unimplemented(call.getString("type") + " is not support now");
|
|
116
142
|
return;
|
|
117
143
|
}
|
|
118
144
|
|
|
119
|
-
final DiscoveryConfiguration config = new DiscoveryConfiguration(0, this.type, this.isTest, call.getString("locationId"));
|
|
120
145
|
final DiscoveryListener discoveryListener = readers -> {
|
|
121
146
|
// 検索したReaderの一覧をListenerで渡す
|
|
122
147
|
Log.d(logTag, String.valueOf(readers.get(0).getSerialNumber()));
|
|
@@ -131,37 +156,39 @@ public class StripeTerminal extends Executor {
|
|
|
131
156
|
call.resolve(new JSObject().put("readers", readersJSObject));
|
|
132
157
|
};
|
|
133
158
|
discoveryCancelable =
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
);
|
|
159
|
+
Terminal.getInstance()
|
|
160
|
+
.discoverReaders(
|
|
161
|
+
config,
|
|
162
|
+
discoveryListener,
|
|
163
|
+
new Callback() {
|
|
164
|
+
@Override
|
|
165
|
+
public void onSuccess() {
|
|
166
|
+
Log.d(logTag, "Finished discovering readers");
|
|
167
|
+
}
|
|
168
|
+
@Override
|
|
169
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
170
|
+
Log.d(logTag, ex.getLocalizedMessage());
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
);
|
|
152
174
|
}
|
|
153
175
|
|
|
154
176
|
public void connectReader(final PluginCall call) {
|
|
155
|
-
if (this.
|
|
177
|
+
if (this.terminalConnectType == TerminalConnectTypes.TapToPay) {
|
|
156
178
|
this.connectLocalMobileReader(call);
|
|
157
|
-
} else if (this.
|
|
179
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Internet) {
|
|
158
180
|
this.connectInternetReader(call);
|
|
181
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Usb) {
|
|
182
|
+
this.connectUsbReader(call);
|
|
183
|
+
} else if (this.terminalConnectType == TerminalConnectTypes.Bluetooth) {
|
|
184
|
+
this.connectBluetoothReader(call);
|
|
185
|
+
} else {
|
|
186
|
+
call.reject("type is not defined.");
|
|
159
187
|
}
|
|
160
188
|
}
|
|
161
189
|
|
|
162
190
|
public void getConnectedReader(final PluginCall call) {
|
|
163
191
|
Reader reader = Terminal.getInstance().getConnectedReader();
|
|
164
|
-
|
|
165
192
|
if (reader == null) {
|
|
166
193
|
call.resolve(new JSObject().put("reader", JSObject.NULL));
|
|
167
194
|
} else {
|
|
@@ -195,7 +222,13 @@ public class StripeTerminal extends Executor {
|
|
|
195
222
|
|
|
196
223
|
private void connectLocalMobileReader(final PluginCall call) {
|
|
197
224
|
JSObject reader = call.getObject("reader");
|
|
198
|
-
|
|
225
|
+
|
|
226
|
+
if (reader.getInteger("index") == null) {
|
|
227
|
+
call.reject("The reader value is not set correctly.");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
LocalMobileConnectionConfiguration config = new LocalMobileConnectionConfiguration(
|
|
199
232
|
this.locationId
|
|
200
233
|
);
|
|
201
234
|
Terminal
|
|
@@ -203,46 +236,48 @@ public class StripeTerminal extends Executor {
|
|
|
203
236
|
.connectLocalMobileReader(
|
|
204
237
|
this.readers.get(reader.getInteger("index")),
|
|
205
238
|
config,
|
|
206
|
-
|
|
207
|
-
@Override
|
|
208
|
-
public void onSuccess(Reader r) {
|
|
209
|
-
notifyListeners(TerminalEnumEvent.ConnectedReader.getWebEventName(), emptyObject);
|
|
210
|
-
call.resolve();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
@Override
|
|
214
|
-
public void onFailure(@NonNull TerminalException ex) {
|
|
215
|
-
ex.printStackTrace();
|
|
216
|
-
call.reject(ex.getLocalizedMessage(), ex);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
239
|
+
this.readerCallback(call)
|
|
219
240
|
);
|
|
220
241
|
}
|
|
221
242
|
|
|
222
243
|
private void connectInternetReader(final PluginCall call) {
|
|
223
244
|
JSObject reader = call.getObject("reader");
|
|
224
|
-
|
|
245
|
+
InternetConnectionConfiguration config = new InternetConnectionConfiguration();
|
|
225
246
|
Terminal
|
|
226
247
|
.getInstance()
|
|
227
248
|
.connectInternetReader(
|
|
228
249
|
this.readers.get(reader.getInteger("index")),
|
|
229
250
|
config,
|
|
230
|
-
|
|
231
|
-
@Override
|
|
232
|
-
public void onSuccess(@NonNull Reader r) {
|
|
233
|
-
notifyListeners(TerminalEnumEvent.ConnectedReader.getWebEventName(), emptyObject);
|
|
234
|
-
call.resolve();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
@Override
|
|
238
|
-
public void onFailure(@NonNull TerminalException ex) {
|
|
239
|
-
ex.printStackTrace();
|
|
240
|
-
call.reject(ex.getLocalizedMessage(), ex);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
251
|
+
this.readerCallback(call)
|
|
243
252
|
);
|
|
244
253
|
}
|
|
245
254
|
|
|
255
|
+
private void connectUsbReader(final PluginCall call) {
|
|
256
|
+
JSObject reader = call.getObject("reader");
|
|
257
|
+
UsbConnectionConfiguration config = new UsbConnectionConfiguration(this.locationId);
|
|
258
|
+
Terminal
|
|
259
|
+
.getInstance()
|
|
260
|
+
.connectUsbReader(
|
|
261
|
+
this.readers.get(reader.getInteger("index")),
|
|
262
|
+
config,
|
|
263
|
+
this.readerListener(),
|
|
264
|
+
this.readerCallback(call)
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private void connectBluetoothReader(final PluginCall call) {
|
|
269
|
+
JSObject reader = call.getObject("reader");
|
|
270
|
+
BluetoothConnectionConfiguration config = new BluetoothConnectionConfiguration(this.locationId);
|
|
271
|
+
Terminal
|
|
272
|
+
.getInstance()
|
|
273
|
+
.connectBluetoothReader(
|
|
274
|
+
this.readers.get(reader.getInteger("index")),
|
|
275
|
+
config,
|
|
276
|
+
this.readerListener(),
|
|
277
|
+
this.readerCallback(call)
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
246
281
|
public void cancelDiscoverReaders(final PluginCall call) {
|
|
247
282
|
if (discoveryCancelable != null) {
|
|
248
283
|
discoveryCancelable.cancel(
|
|
@@ -254,7 +289,7 @@ public class StripeTerminal extends Executor {
|
|
|
254
289
|
}
|
|
255
290
|
|
|
256
291
|
@Override
|
|
257
|
-
public void onFailure(TerminalException ex) {
|
|
292
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
258
293
|
call.reject(ex.getLocalizedMessage(), ex);
|
|
259
294
|
}
|
|
260
295
|
}
|
|
@@ -265,9 +300,11 @@ public class StripeTerminal extends Executor {
|
|
|
265
300
|
}
|
|
266
301
|
|
|
267
302
|
public void collect(final PluginCall call) {
|
|
268
|
-
|
|
303
|
+
if (call.getString("paymentIntent") == null) {
|
|
304
|
+
call.reject("The value of paymentIntent is not set correctly.");
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
269
307
|
this.collectCall = call;
|
|
270
|
-
|
|
271
308
|
Terminal.getInstance().retrievePaymentIntent(call.getString("paymentIntent"), createPaymentIntentCallback);
|
|
272
309
|
}
|
|
273
310
|
|
|
@@ -297,7 +334,10 @@ public class StripeTerminal extends Executor {
|
|
|
297
334
|
private final PaymentIntentCallback createPaymentIntentCallback = new PaymentIntentCallback() {
|
|
298
335
|
@Override
|
|
299
336
|
public void onSuccess(@NonNull PaymentIntent paymentIntent) {
|
|
300
|
-
|
|
337
|
+
CollectConfiguration collectConfig = new CollectConfiguration.Builder()
|
|
338
|
+
.updatePaymentIntent(true)
|
|
339
|
+
.build();
|
|
340
|
+
collectCancelable = Terminal.getInstance().collectPaymentMethod(paymentIntent, collectPaymentMethodCallback, collectConfig);
|
|
301
341
|
}
|
|
302
342
|
|
|
303
343
|
@Override
|
|
@@ -310,9 +350,34 @@ public class StripeTerminal extends Executor {
|
|
|
310
350
|
// Step 3 - we've collected the payment method, so it's time to process the payment
|
|
311
351
|
private final PaymentIntentCallback collectPaymentMethodCallback = new PaymentIntentCallback() {
|
|
312
352
|
@Override
|
|
313
|
-
public void onSuccess(
|
|
353
|
+
public void onSuccess(PaymentIntent paymentIntent) {
|
|
314
354
|
collectCancelable = null;
|
|
315
|
-
|
|
355
|
+
notifyListeners(TerminalEnumEvent.Completed.getWebEventName(), emptyObject);
|
|
356
|
+
|
|
357
|
+
PaymentMethod pm = paymentIntent.getPaymentMethod();
|
|
358
|
+
CardPresentDetails card = pm.getCardPresentDetails() != null
|
|
359
|
+
? pm.getCardPresentDetails()
|
|
360
|
+
: pm.getInteracPresentDetails();
|
|
361
|
+
|
|
362
|
+
if (card != null) {
|
|
363
|
+
collectCall.resolve(new JSObject()
|
|
364
|
+
.put("brand", card.getBrand())
|
|
365
|
+
.put("cardholderName", card.getCardholderName())
|
|
366
|
+
.put("country", card.getCountry())
|
|
367
|
+
.put("emvAuthData", card.getEmvAuthData())
|
|
368
|
+
.put("expMonth", card.getExpMonth())
|
|
369
|
+
.put("expYear", card.getExpYear())
|
|
370
|
+
.put("funding", card.getFunding())
|
|
371
|
+
.put("generatedCard", card.getGeneratedCard())
|
|
372
|
+
.put("incrementalAuthorizationStatus", card.getIncrementalAuthorizationStatus())
|
|
373
|
+
.put("last4", card.getLast4())
|
|
374
|
+
.put("networks", card.getNetworks())
|
|
375
|
+
.put("readMethod", card.getReadMethod())
|
|
376
|
+
|
|
377
|
+
);
|
|
378
|
+
} else {
|
|
379
|
+
collectCall.resolve();
|
|
380
|
+
}
|
|
316
381
|
}
|
|
317
382
|
|
|
318
383
|
@Override
|
|
@@ -323,18 +388,49 @@ public class StripeTerminal extends Executor {
|
|
|
323
388
|
}
|
|
324
389
|
};
|
|
325
390
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
391
|
+
private ReaderCallback readerCallback(final PluginCall call) {
|
|
392
|
+
return new ReaderCallback() {
|
|
393
|
+
@Override
|
|
394
|
+
public void onSuccess(@NonNull Reader r) {
|
|
395
|
+
notifyListeners(TerminalEnumEvent.ConnectedReader.getWebEventName(), emptyObject);
|
|
396
|
+
call.resolve();
|
|
397
|
+
}
|
|
333
398
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
399
|
+
@Override
|
|
400
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
401
|
+
ex.printStackTrace();
|
|
402
|
+
call.reject(ex.getLocalizedMessage(), ex);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private ReaderListener readerListener() {
|
|
408
|
+
return new ReaderListener() {
|
|
409
|
+
@Override
|
|
410
|
+
public void onStartInstallingUpdate(@NotNull ReaderSoftwareUpdate update, @NotNull Cancelable cancelable) {
|
|
411
|
+
// Show UI communicating that a required update has started installing
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
@Override
|
|
415
|
+
public void onReportReaderSoftwareUpdateProgress(float progress) {
|
|
416
|
+
// Update the progress of the install
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@Override
|
|
420
|
+
public void onFinishInstallingUpdate(@Nullable ReaderSoftwareUpdate update, @Nullable TerminalException e) {
|
|
421
|
+
// Report success or failure of the update
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@Override
|
|
425
|
+
public void onReportLowBatteryWarning() {
|
|
426
|
+
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
@Override
|
|
430
|
+
public void onReportAvailableUpdate(@NotNull ReaderSoftwareUpdate update) {
|
|
431
|
+
// An update is available for the connected reader. Show this update in your application.
|
|
432
|
+
// This update can be installed using `Terminal.getInstance().installAvailableUpdate`.
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
340
436
|
}
|
package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java
CHANGED
|
@@ -2,7 +2,9 @@ package com.getcapacitor.community.stripe.terminal;
|
|
|
2
2
|
|
|
3
3
|
import android.Manifest;
|
|
4
4
|
import android.os.Build;
|
|
5
|
+
|
|
5
6
|
import androidx.annotation.RequiresApi;
|
|
7
|
+
|
|
6
8
|
import com.getcapacitor.PermissionState;
|
|
7
9
|
import com.getcapacitor.Plugin;
|
|
8
10
|
import com.getcapacitor.PluginCall;
|
|
@@ -11,8 +13,6 @@ import com.getcapacitor.annotation.CapacitorPlugin;
|
|
|
11
13
|
import com.getcapacitor.annotation.Permission;
|
|
12
14
|
import com.getcapacitor.annotation.PermissionCallback;
|
|
13
15
|
import com.stripe.stripeterminal.external.models.TerminalException;
|
|
14
|
-
import java.util.Objects;
|
|
15
|
-
import org.json.JSONException;
|
|
16
16
|
|
|
17
17
|
@RequiresApi(api = Build.VERSION_CODES.S)
|
|
18
18
|
@CapacitorPlugin(
|
|
@@ -2,7 +2,9 @@ package com.getcapacitor.community.stripe.terminal;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.util.Log;
|
|
5
|
+
|
|
5
6
|
import androidx.core.util.Supplier;
|
|
7
|
+
|
|
6
8
|
import com.android.volley.Request;
|
|
7
9
|
import com.android.volley.RequestQueue;
|
|
8
10
|
import com.android.volley.Response;
|
|
@@ -12,6 +14,7 @@ import com.android.volley.toolbox.Volley;
|
|
|
12
14
|
import com.stripe.stripeterminal.external.callable.ConnectionTokenCallback;
|
|
13
15
|
import com.stripe.stripeterminal.external.callable.ConnectionTokenProvider;
|
|
14
16
|
import com.stripe.stripeterminal.external.models.ConnectionTokenException;
|
|
17
|
+
|
|
15
18
|
import org.json.JSONException;
|
|
16
19
|
import org.json.JSONObject;
|
|
17
20
|
|
package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/MetaData.java
CHANGED
|
@@ -3,7 +3,9 @@ package com.getcapacitor.community.stripe.terminal.helper;
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.content.pm.ApplicationInfo;
|
|
5
5
|
import android.content.pm.PackageManager;
|
|
6
|
+
|
|
6
7
|
import androidx.core.util.Supplier;
|
|
8
|
+
|
|
7
9
|
import com.getcapacitor.Logger;
|
|
8
10
|
|
|
9
11
|
public class MetaData {
|
package/android/src/main/java/com/getcapacitor/community/stripe/terminal/models/Executor.java
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
package com.getcapacitor.community.stripe.terminal.models;
|
|
2
2
|
|
|
3
3
|
import android.app.Activity;
|
|
4
|
-
import android.app.Application;
|
|
5
4
|
import android.content.Context;
|
|
5
|
+
|
|
6
6
|
import androidx.core.util.Supplier;
|
|
7
|
+
|
|
7
8
|
import com.getcapacitor.JSObject;
|
|
8
|
-
import com.getcapacitor.Plugin;
|
|
9
9
|
import com.google.android.gms.common.util.BiConsumer;
|
|
10
|
-
import com.stripe.stripeterminal.TerminalApplicationDelegate;
|
|
11
10
|
|
|
12
11
|
public abstract class Executor {
|
|
13
12
|
|
|
@@ -2,7 +2,7 @@ import Foundation
|
|
|
2
2
|
import Capacitor
|
|
3
3
|
import StripeTerminal
|
|
4
4
|
|
|
5
|
-
public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDelegate {
|
|
5
|
+
public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDelegate, BluetoothReaderDelegate {
|
|
6
6
|
|
|
7
7
|
weak var plugin: StripeTerminalPlugin?
|
|
8
8
|
var discoverCancelable: Cancelable?
|
|
@@ -25,22 +25,26 @@ public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDeleg
|
|
|
25
25
|
call.resolve()
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
func discoverReaders(_ call: CAPPluginCall) {
|
|
28
|
+
func discoverReaders(_ call: CAPPluginCall) throws {
|
|
29
29
|
let connectType = call.getString("type")
|
|
30
30
|
|
|
31
31
|
if TerminalConnectTypes.TapToPay.rawValue == connectType {
|
|
32
32
|
self.type = .localMobile
|
|
33
33
|
} else if TerminalConnectTypes.Internet.rawValue == connectType {
|
|
34
34
|
self.type = .internet
|
|
35
|
+
} else if TerminalConnectTypes.Bluetooth.rawValue == connectType {
|
|
36
|
+
self.type = DiscoveryMethod.bluetoothScan
|
|
35
37
|
} else {
|
|
36
38
|
call.unimplemented(connectType! + " is not support now")
|
|
37
39
|
return
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
|
|
40
43
|
let config = DiscoveryConfiguration(
|
|
41
44
|
discoveryMethod: self.type!,
|
|
42
45
|
simulated: self.isTest!
|
|
43
46
|
)
|
|
47
|
+
|
|
44
48
|
self.discoverCall = call
|
|
45
49
|
self.locationId = call.getString("locationId")
|
|
46
50
|
|
|
@@ -154,6 +158,21 @@ public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDeleg
|
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
}
|
|
161
|
+
|
|
162
|
+
private func connectBluetoothReader(_ call: CAPPluginCall) {
|
|
163
|
+
let config = BluetoothConnectionConfiguration(locationId: self.locationId!)
|
|
164
|
+
let reader: JSObject = call.getObject("reader")!
|
|
165
|
+
let index: Int = reader["index"] as! Int
|
|
166
|
+
|
|
167
|
+
Terminal.shared.connectBluetoothReader(self.readers![index], delegate: self, connectionConfig: config) { reader, error in
|
|
168
|
+
if let reader = reader {
|
|
169
|
+
self.plugin?.notifyListeners(TerminalEvents.ConnectedReader.rawValue, data: [:])
|
|
170
|
+
call.resolve()
|
|
171
|
+
} else if let error = error {
|
|
172
|
+
call.reject(error.localizedDescription)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
157
176
|
|
|
158
177
|
public func collect(_ call: CAPPluginCall) {
|
|
159
178
|
Terminal.shared.retrievePaymentIntent(clientSecret: call.getString("paymentIntent")!) { retrieveResult, retrieveError in
|
|
@@ -188,7 +207,10 @@ public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDeleg
|
|
|
188
207
|
}
|
|
189
208
|
call.resolve()
|
|
190
209
|
}
|
|
210
|
+
|
|
191
211
|
|
|
212
|
+
// localMobile
|
|
213
|
+
|
|
192
214
|
public func localMobileReader(_ reader: Reader, didStartInstallingUpdate update: ReaderSoftwareUpdate, cancelable: Cancelable?) {
|
|
193
215
|
// TODO
|
|
194
216
|
}
|
|
@@ -208,6 +230,33 @@ public class StripeTerminal: NSObject, DiscoveryDelegate, LocalMobileReaderDeleg
|
|
|
208
230
|
public func localMobileReader(_ reader: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) {
|
|
209
231
|
// TODO
|
|
210
232
|
}
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
// bluetooth
|
|
236
|
+
|
|
237
|
+
public func reader(_: Reader, didReportAvailableUpdate update: ReaderSoftwareUpdate) {
|
|
238
|
+
// TODO
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
public func reader(_: Reader, didStartInstallingUpdate update: ReaderSoftwareUpdate, cancelable: Cancelable?) {
|
|
242
|
+
// TODO
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
public func reader(_: Reader, didReportReaderSoftwareUpdateProgress progress: Float) {
|
|
246
|
+
// TODO
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
public func reader(_: Reader, didFinishInstallingUpdate update: ReaderSoftwareUpdate?, error: Error?) {
|
|
250
|
+
// TODO
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
public func reader(_: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) {
|
|
254
|
+
// TODO
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public func reader(_: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) {
|
|
258
|
+
// TODO
|
|
259
|
+
}
|
|
211
260
|
}
|
|
212
261
|
|
|
213
262
|
class APIClient: ConnectionTokenProvider {
|
|
@@ -22,7 +22,11 @@ public class StripeTerminalPlugin: CAPPlugin {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@objc func discoverReaders(_ call: CAPPluginCall) {
|
|
25
|
-
|
|
25
|
+
do {
|
|
26
|
+
try self.implementation.discoverReaders(call)
|
|
27
|
+
} catch {
|
|
28
|
+
call.reject("discoverReaders throw error.")
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
@objc func cancelDiscoverReaders(_ call: CAPPluginCall) {
|