@capacitor-community/stripe-terminal 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.
- package/CapacitorCommunityStripeTerminal.podspec +18 -0
- package/README.md +263 -0
- package/android/build.gradle +70 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminal.java +227 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java +93 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TerminalEvent.kt +10 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/TokenProvider.java +67 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/helper/MetaData.java +28 -0
- package/android/src/main/java/com/getcapacitor/community/stripe/terminal/models/Executor.java +36 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +337 -0
- package/dist/esm/definitions.d.ts +40 -0
- package/dist/esm/definitions.js +10 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/events.enum.d.ts +9 -0
- package/dist/esm/events.enum.js +10 -0
- package/dist/esm/events.enum.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +20 -0
- package/dist/esm/web.js +26 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +60 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +63 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/StripeTerminal.swift +155 -0
- package/ios/Plugin/StripeTerminalPlugin.h +10 -0
- package/ios/Plugin/StripeTerminalPlugin.m +11 -0
- package/ios/Plugin/StripeTerminalPlugin.swift +35 -0
- package/ios/Plugin/TerminalEvents.swift +8 -0
- package/package.json +78 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'CapacitorCommunityStripeTerminal'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '13.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.dependency 'StripeTerminal'
|
|
17
|
+
s.swift_version = '5.1'
|
|
18
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# @capacitor-community/stripe-terminal
|
|
2
|
+
|
|
3
|
+
Stripe SDK bindings for Capacitor Applications. __This plugin is still in beta.__
|
|
4
|
+
We have confirmed that it works well in the demo project. Please refer to https://github.com/capacitor-community/stripe/tree/main/demo/angular for the implementation.
|
|
5
|
+
|
|
6
|
+
- [x] Tap To Pay
|
|
7
|
+
- [ ] Internet
|
|
8
|
+
- [ ] Bluetooth
|
|
9
|
+
- [ ] USB
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @capacitor-community/stripe-terminal
|
|
15
|
+
npx cap sync
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### iOS
|
|
19
|
+
|
|
20
|
+
- [iOS Configure your app](https://stripe.com/docs/terminal/payments/setup-integration?terminal-sdk-platform=ios#configure)
|
|
21
|
+
|
|
22
|
+
### Android
|
|
23
|
+
|
|
24
|
+
Add permissions to your `android/app/src/main/AndroidManifest.xml` file:
|
|
25
|
+
|
|
26
|
+
```diff
|
|
27
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH" />
|
|
28
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
|
29
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
|
30
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
|
31
|
+
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If used in conjunction with the `@capacitor-community/stripe` plugin, the following settings may be necessary
|
|
35
|
+
|
|
36
|
+
Add packagingOptions to your `android/app/build.gradle` file:
|
|
37
|
+
|
|
38
|
+
```diff
|
|
39
|
+
android {
|
|
40
|
+
...
|
|
41
|
+
+ packagingOptions {
|
|
42
|
+
+ resources.excludes.add("org/bouncycastle/x509/*")
|
|
43
|
+
+ }
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
<docgen-index>
|
|
50
|
+
|
|
51
|
+
* [`initialize(...)`](#initialize)
|
|
52
|
+
* [`discoverReaders(...)`](#discoverreaders)
|
|
53
|
+
* [`connectReader(...)`](#connectreader)
|
|
54
|
+
* [`collect(...)`](#collect)
|
|
55
|
+
* [`addListener(TerminalEventsEnum.Loaded, ...)`](#addlistenerterminaleventsenumloaded)
|
|
56
|
+
* [`addListener(TerminalEventsEnum.DiscoveredReaders, ...)`](#addlistenerterminaleventsenumdiscoveredreaders)
|
|
57
|
+
* [`addListener(TerminalEventsEnum.ConnectedReader, ...)`](#addlistenerterminaleventsenumconnectedreader)
|
|
58
|
+
* [`addListener(TerminalEventsEnum.Completed, ...)`](#addlistenerterminaleventsenumcompleted)
|
|
59
|
+
* [`addListener(TerminalEventsEnum.Canceled, ...)`](#addlistenerterminaleventsenumcanceled)
|
|
60
|
+
* [`addListener(TerminalEventsEnum.Failed, ...)`](#addlistenerterminaleventsenumfailed)
|
|
61
|
+
* [Interfaces](#interfaces)
|
|
62
|
+
* [Type Aliases](#type-aliases)
|
|
63
|
+
* [Enums](#enums)
|
|
64
|
+
|
|
65
|
+
</docgen-index>
|
|
66
|
+
|
|
67
|
+
<docgen-api>
|
|
68
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
69
|
+
|
|
70
|
+
### initialize(...)
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
initialize(options: { tokenProviderEndpoint: string; isTest: boolean; }) => Promise<void>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| Param | Type |
|
|
77
|
+
| ------------- | ---------------------------------------------------------------- |
|
|
78
|
+
| **`options`** | <code>{ tokenProviderEndpoint: string; isTest: boolean; }</code> |
|
|
79
|
+
|
|
80
|
+
--------------------
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
### discoverReaders(...)
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
discoverReaders(options: { type: TerminalConnectType; locationId?: string; }) => Promise<{ readers: ReaderInterface[]; }>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
| Param | Type |
|
|
90
|
+
| ------------- | --------------------------------------------------------------------------------------------------- |
|
|
91
|
+
| **`options`** | <code>{ type: <a href="#terminalconnecttype">TerminalConnectType</a>; locationId?: string; }</code> |
|
|
92
|
+
|
|
93
|
+
**Returns:** <code>Promise<{ readers: ReaderInterface[]; }></code>
|
|
94
|
+
|
|
95
|
+
--------------------
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### connectReader(...)
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
connectReader(options: { reader: ReaderInterface; }) => Promise<void>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Param | Type |
|
|
105
|
+
| ------------- | ------------------------------------------------------------------------ |
|
|
106
|
+
| **`options`** | <code>{ reader: <a href="#readerinterface">ReaderInterface</a>; }</code> |
|
|
107
|
+
|
|
108
|
+
--------------------
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
### collect(...)
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
collect(options: { paymentIntent: string; }) => Promise<void>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
| Param | Type |
|
|
118
|
+
| ------------- | --------------------------------------- |
|
|
119
|
+
| **`options`** | <code>{ paymentIntent: string; }</code> |
|
|
120
|
+
|
|
121
|
+
--------------------
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
### addListener(TerminalEventsEnum.Loaded, ...)
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
addListener(eventName: TerminalEventsEnum.Loaded, listenerFunc: () => void) => PluginListenerHandle
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
| Param | Type |
|
|
131
|
+
| ------------------ | ------------------------------------------------------------------------ |
|
|
132
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.Loaded</a></code> |
|
|
133
|
+
| **`listenerFunc`** | <code>() => void</code> |
|
|
134
|
+
|
|
135
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
136
|
+
|
|
137
|
+
--------------------
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
### addListener(TerminalEventsEnum.DiscoveredReaders, ...)
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
addListener(eventName: TerminalEventsEnum.DiscoveredReaders, listenerFunc: () => { reader: ReaderInterface; }) => PluginListenerHandle
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Param | Type |
|
|
147
|
+
| ------------------ | ----------------------------------------------------------------------------------- |
|
|
148
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.DiscoveredReaders</a></code> |
|
|
149
|
+
| **`listenerFunc`** | <code>() => { reader: <a href="#readerinterface">ReaderInterface</a>; }</code> |
|
|
150
|
+
|
|
151
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
152
|
+
|
|
153
|
+
--------------------
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
### addListener(TerminalEventsEnum.ConnectedReader, ...)
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
addListener(eventName: TerminalEventsEnum.ConnectedReader, listenerFunc: () => void) => PluginListenerHandle
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Param | Type |
|
|
163
|
+
| ------------------ | --------------------------------------------------------------------------------- |
|
|
164
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.ConnectedReader</a></code> |
|
|
165
|
+
| **`listenerFunc`** | <code>() => void</code> |
|
|
166
|
+
|
|
167
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
168
|
+
|
|
169
|
+
--------------------
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
### addListener(TerminalEventsEnum.Completed, ...)
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
addListener(eventName: TerminalEventsEnum.Completed, listenerFunc: () => void) => PluginListenerHandle
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
| Param | Type |
|
|
179
|
+
| ------------------ | --------------------------------------------------------------------------- |
|
|
180
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.Completed</a></code> |
|
|
181
|
+
| **`listenerFunc`** | <code>() => void</code> |
|
|
182
|
+
|
|
183
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
184
|
+
|
|
185
|
+
--------------------
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
### addListener(TerminalEventsEnum.Canceled, ...)
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
addListener(eventName: TerminalEventsEnum.Canceled, listenerFunc: () => void) => PluginListenerHandle
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
| Param | Type |
|
|
195
|
+
| ------------------ | -------------------------------------------------------------------------- |
|
|
196
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.Canceled</a></code> |
|
|
197
|
+
| **`listenerFunc`** | <code>() => void</code> |
|
|
198
|
+
|
|
199
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
200
|
+
|
|
201
|
+
--------------------
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
### addListener(TerminalEventsEnum.Failed, ...)
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
addListener(eventName: TerminalEventsEnum.Failed, listenerFunc: () => void) => PluginListenerHandle
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
| Param | Type |
|
|
211
|
+
| ------------------ | ------------------------------------------------------------------------ |
|
|
212
|
+
| **`eventName`** | <code><a href="#terminaleventsenum">TerminalEventsEnum.Failed</a></code> |
|
|
213
|
+
| **`listenerFunc`** | <code>() => void</code> |
|
|
214
|
+
|
|
215
|
+
**Returns:** <code><a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
216
|
+
|
|
217
|
+
--------------------
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
### Interfaces
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
#### PluginListenerHandle
|
|
224
|
+
|
|
225
|
+
| Prop | Type |
|
|
226
|
+
| ------------ | ----------------------------------------- |
|
|
227
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
### Type Aliases
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
#### ReaderInterface
|
|
234
|
+
|
|
235
|
+
<code>{ index: number; serialNumber: string; }</code>
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
### Enums
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
#### TerminalConnectType
|
|
242
|
+
|
|
243
|
+
| Members | Value |
|
|
244
|
+
| --------------- | ------------------------- |
|
|
245
|
+
| **`Simulated`** | <code>'simulated'</code> |
|
|
246
|
+
| **`Internet`** | <code>'internet'</code> |
|
|
247
|
+
| **`Bluetooth`** | <code>'bluetooth'</code> |
|
|
248
|
+
| **`Usb`** | <code>'usb'</code> |
|
|
249
|
+
| **`TapToPay`** | <code>'tap-to-pay'</code> |
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
#### TerminalEventsEnum
|
|
253
|
+
|
|
254
|
+
| Members | Value |
|
|
255
|
+
| ----------------------- | ---------------------------------------- |
|
|
256
|
+
| **`Loaded`** | <code>'terminalLoaded'</code> |
|
|
257
|
+
| **`DiscoveredReaders`** | <code>'terminalDiscoveredReaders'</code> |
|
|
258
|
+
| **`ConnectedReader`** | <code>'terminalConnectedReader'</code> |
|
|
259
|
+
| **`Completed`** | <code>'terminalCompleted'</code> |
|
|
260
|
+
| **`Canceled`** | <code>'terminalCanceled'</code> |
|
|
261
|
+
| **`Failed`** | <code>'terminalFailed'</code> |
|
|
262
|
+
|
|
263
|
+
</docgen-api>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.8.20'
|
|
10
|
+
repositories {
|
|
11
|
+
google()
|
|
12
|
+
mavenCentral()
|
|
13
|
+
}
|
|
14
|
+
dependencies {
|
|
15
|
+
classpath 'com.android.tools.build:gradle:8.0.0'
|
|
16
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
apply plugin: 'com.android.library'
|
|
21
|
+
apply plugin: 'kotlin-android'
|
|
22
|
+
|
|
23
|
+
android {
|
|
24
|
+
namespace "com.getcapacitor.community.stripe.terminal"
|
|
25
|
+
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
|
|
26
|
+
defaultConfig {
|
|
27
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
|
28
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
|
|
29
|
+
versionCode 1
|
|
30
|
+
versionName "1.0"
|
|
31
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
32
|
+
}
|
|
33
|
+
buildTypes {
|
|
34
|
+
release {
|
|
35
|
+
minifyEnabled false
|
|
36
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
lintOptions {
|
|
40
|
+
abortOnError false
|
|
41
|
+
}
|
|
42
|
+
compileOptions {
|
|
43
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
44
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
45
|
+
}
|
|
46
|
+
kotlinOptions {
|
|
47
|
+
jvmTarget = "1.8"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
repositories {
|
|
52
|
+
google()
|
|
53
|
+
mavenCentral()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
dependencies {
|
|
58
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
59
|
+
implementation project(':capacitor-android')
|
|
60
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
61
|
+
testImplementation "junit:junit:$junitVersion"
|
|
62
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
63
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
64
|
+
|
|
65
|
+
implementation "com.stripe:stripeterminal-localmobile:2.23.0"
|
|
66
|
+
implementation "com.stripe:stripeterminal-core:2.23.0"
|
|
67
|
+
implementation 'com.android.volley:volley:1.2.1'
|
|
68
|
+
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
|
|
69
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
70
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
package com.getcapacitor.community.stripe.terminal;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.app.Application;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.content.pm.ApplicationInfo;
|
|
7
|
+
import android.util.Log;
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
import androidx.core.util.Supplier;
|
|
10
|
+
import com.getcapacitor.JSArray;
|
|
11
|
+
import com.getcapacitor.JSObject;
|
|
12
|
+
import com.getcapacitor.PluginCall;
|
|
13
|
+
import com.getcapacitor.community.stripe.terminal.models.Executor;
|
|
14
|
+
import com.google.android.gms.common.util.BiConsumer;
|
|
15
|
+
import com.stripe.stripeterminal.Terminal;
|
|
16
|
+
import com.stripe.stripeterminal.TerminalApplicationDelegate;
|
|
17
|
+
import com.stripe.stripeterminal.external.callable.Callback;
|
|
18
|
+
import com.stripe.stripeterminal.external.callable.Cancelable;
|
|
19
|
+
import com.stripe.stripeterminal.external.callable.DiscoveryListener;
|
|
20
|
+
import com.stripe.stripeterminal.external.callable.PaymentIntentCallback;
|
|
21
|
+
import com.stripe.stripeterminal.external.callable.ReaderCallback;
|
|
22
|
+
import com.stripe.stripeterminal.external.callable.TerminalListener;
|
|
23
|
+
import com.stripe.stripeterminal.external.models.ConnectionConfiguration;
|
|
24
|
+
import com.stripe.stripeterminal.external.models.ConnectionStatus;
|
|
25
|
+
import com.stripe.stripeterminal.external.models.DiscoveryConfiguration;
|
|
26
|
+
import com.stripe.stripeterminal.external.models.DiscoveryMethod;
|
|
27
|
+
import com.stripe.stripeterminal.external.models.PaymentIntent;
|
|
28
|
+
import com.stripe.stripeterminal.external.models.PaymentStatus;
|
|
29
|
+
import com.stripe.stripeterminal.external.models.Reader;
|
|
30
|
+
import com.stripe.stripeterminal.external.models.TerminalException;
|
|
31
|
+
import com.stripe.stripeterminal.log.LogLevel;
|
|
32
|
+
import java.util.ArrayList;
|
|
33
|
+
import java.util.List;
|
|
34
|
+
import org.json.JSONException;
|
|
35
|
+
|
|
36
|
+
public class StripeTerminal extends Executor {
|
|
37
|
+
|
|
38
|
+
private Cancelable discoveryCancelable;
|
|
39
|
+
private List<Reader> readers;
|
|
40
|
+
private String locationId;
|
|
41
|
+
private PluginCall collectCall;
|
|
42
|
+
private final JSObject emptyObject = new JSObject();
|
|
43
|
+
private Boolean isTest;
|
|
44
|
+
|
|
45
|
+
public StripeTerminal(
|
|
46
|
+
Supplier<Context> contextSupplier,
|
|
47
|
+
Supplier<Activity> activitySupplier,
|
|
48
|
+
BiConsumer<String, JSObject> notifyListenersFunction,
|
|
49
|
+
String pluginLogTag
|
|
50
|
+
) {
|
|
51
|
+
super(contextSupplier, activitySupplier, notifyListenersFunction, pluginLogTag, "StripeTerminalExecutor");
|
|
52
|
+
this.contextSupplier = contextSupplier;
|
|
53
|
+
this.readers = new ArrayList<Reader>();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public void initialize(final PluginCall call) throws TerminalException {
|
|
57
|
+
this.isTest = call.getBoolean("isTest", true);
|
|
58
|
+
this.activitySupplier.get()
|
|
59
|
+
.runOnUiThread(
|
|
60
|
+
() -> {
|
|
61
|
+
TerminalApplicationDelegate.onCreate((Application) this.contextSupplier.get().getApplicationContext());
|
|
62
|
+
notifyListeners(TerminalEnumEvent.Loaded.getWebEventName(), emptyObject);
|
|
63
|
+
call.resolve();
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
TerminalListener listener = new TerminalListener() {
|
|
67
|
+
@Override
|
|
68
|
+
public void onUnexpectedReaderDisconnect(@NonNull Reader reader) {
|
|
69
|
+
// TODO: Listenerを追加
|
|
70
|
+
}
|
|
71
|
+
//
|
|
72
|
+
// @Override
|
|
73
|
+
// public void onConnectionStatusChange(@NonNull ConnectionStatus status) {
|
|
74
|
+
// // TODO: Listenerを追加
|
|
75
|
+
// }
|
|
76
|
+
//
|
|
77
|
+
// @Override
|
|
78
|
+
// public void onPaymentStatusChange(@NonNull PaymentStatus status) {
|
|
79
|
+
// // TODO: Listenerを追加
|
|
80
|
+
// }
|
|
81
|
+
};
|
|
82
|
+
LogLevel logLevel = LogLevel.VERBOSE;
|
|
83
|
+
TokenProvider tokenProvider = new TokenProvider(this.contextSupplier, call.getString("tokenProviderEndpoint"));
|
|
84
|
+
if (!Terminal.isInitialized()) {
|
|
85
|
+
Terminal.initTerminal(this.contextSupplier.get().getApplicationContext(), logLevel, tokenProvider, listener);
|
|
86
|
+
}
|
|
87
|
+
Terminal.getInstance();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public void onDiscoverReaders(final PluginCall call) {
|
|
91
|
+
this.locationId = call.getString("locationId");
|
|
92
|
+
final DiscoveryConfiguration config = new DiscoveryConfiguration(
|
|
93
|
+
0,
|
|
94
|
+
DiscoveryMethod.LOCAL_MOBILE,
|
|
95
|
+
this.isTest,
|
|
96
|
+
call.getString("locationId")
|
|
97
|
+
);
|
|
98
|
+
final DiscoveryListener discoveryListener = readers -> {
|
|
99
|
+
// 検索したReaderの一覧をListenerで渡す
|
|
100
|
+
Log.d(logTag, String.valueOf(readers.get(0).getSerialNumber()));
|
|
101
|
+
this.readers = readers;
|
|
102
|
+
JSArray readersJSObject = new JSArray();
|
|
103
|
+
|
|
104
|
+
int i = 0;
|
|
105
|
+
for (Reader reader : this.readers) {
|
|
106
|
+
readersJSObject.put(new JSObject().put("index", String.valueOf(i)).put("serialNumber", reader.getSerialNumber()));
|
|
107
|
+
}
|
|
108
|
+
this.notifyListeners(TerminalEnumEvent.DiscoveredReaders.getWebEventName(), new JSObject().put("readers", readersJSObject));
|
|
109
|
+
call.resolve(new JSObject().put("readers", readersJSObject));
|
|
110
|
+
};
|
|
111
|
+
discoveryCancelable =
|
|
112
|
+
Terminal
|
|
113
|
+
.getInstance()
|
|
114
|
+
.discoverReaders(
|
|
115
|
+
config,
|
|
116
|
+
discoveryListener,
|
|
117
|
+
// Callback run after connectReader
|
|
118
|
+
new Callback() {
|
|
119
|
+
@Override
|
|
120
|
+
public void onSuccess() {
|
|
121
|
+
Log.d(logTag, "Finished discovering readers");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Override
|
|
125
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
126
|
+
Log.d(logTag, ex.getLocalizedMessage());
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public void connectReader(final PluginCall call) {
|
|
133
|
+
JSObject reader = call.getObject("reader");
|
|
134
|
+
ConnectionConfiguration.LocalMobileConnectionConfiguration config = new ConnectionConfiguration.LocalMobileConnectionConfiguration(
|
|
135
|
+
this.locationId
|
|
136
|
+
);
|
|
137
|
+
Terminal
|
|
138
|
+
.getInstance()
|
|
139
|
+
.connectLocalMobileReader(
|
|
140
|
+
this.readers.get(reader.getInteger("index")),
|
|
141
|
+
config,
|
|
142
|
+
new ReaderCallback() {
|
|
143
|
+
@Override
|
|
144
|
+
public void onSuccess(Reader r) {
|
|
145
|
+
notifyListeners(TerminalEnumEvent.ConnectedReader.getWebEventName(), emptyObject);
|
|
146
|
+
call.resolve();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@Override
|
|
150
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
151
|
+
ex.printStackTrace();
|
|
152
|
+
call.reject(ex.getLocalizedMessage(), ex);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public void cancelDiscovering(final PluginCall call) {
|
|
159
|
+
if (discoveryCancelable != null) {
|
|
160
|
+
discoveryCancelable.cancel(
|
|
161
|
+
new Callback() {
|
|
162
|
+
@Override
|
|
163
|
+
public void onSuccess() {
|
|
164
|
+
call.resolve();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@Override
|
|
168
|
+
public void onFailure(TerminalException ex) {
|
|
169
|
+
Log.d(logTag, ex.getLocalizedMessage());
|
|
170
|
+
call.reject(ex.getLocalizedMessage(), ex);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
} else {
|
|
175
|
+
call.resolve();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public void collect(final PluginCall call) {
|
|
180
|
+
// メソッドを分割するためcallを永続化
|
|
181
|
+
this.collectCall = call;
|
|
182
|
+
|
|
183
|
+
Terminal.getInstance().retrievePaymentIntent(call.getString("paymentIntent"), createPaymentIntentCallback);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private final PaymentIntentCallback createPaymentIntentCallback = new PaymentIntentCallback() {
|
|
187
|
+
@Override
|
|
188
|
+
public void onSuccess(@NonNull PaymentIntent paymentIntent) {
|
|
189
|
+
Terminal.getInstance().collectPaymentMethod(paymentIntent, collectPaymentMethodCallback);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@Override
|
|
193
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
194
|
+
notifyListeners(TerminalEnumEvent.Failed.getWebEventName(), emptyObject);
|
|
195
|
+
collectCall.reject(ex.getLocalizedMessage(), ex);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Step 3 - we've collected the payment method, so it's time to process the payment
|
|
200
|
+
private final PaymentIntentCallback collectPaymentMethodCallback = new PaymentIntentCallback() {
|
|
201
|
+
@Override
|
|
202
|
+
public void onSuccess(@NonNull PaymentIntent paymentIntent) {
|
|
203
|
+
Terminal.getInstance().processPayment(paymentIntent, processPaymentCallback);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@Override
|
|
207
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
208
|
+
notifyListeners(TerminalEnumEvent.Failed.getWebEventName(), emptyObject);
|
|
209
|
+
collectCall.reject(ex.getLocalizedMessage(), ex);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Step 4 - we've processed the payment! Show a success screen
|
|
214
|
+
private final PaymentIntentCallback processPaymentCallback = new PaymentIntentCallback() {
|
|
215
|
+
@Override
|
|
216
|
+
public void onSuccess(@NonNull PaymentIntent paymentIntent) {
|
|
217
|
+
notifyListeners(TerminalEnumEvent.Completed.getWebEventName(), emptyObject);
|
|
218
|
+
collectCall.resolve();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@Override
|
|
222
|
+
public void onFailure(@NonNull TerminalException ex) {
|
|
223
|
+
notifyListeners(TerminalEnumEvent.Failed.getWebEventName(), emptyObject);
|
|
224
|
+
collectCall.reject(ex.getLocalizedMessage(), ex);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
package/android/src/main/java/com/getcapacitor/community/stripe/terminal/StripeTerminalPlugin.java
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
package com.getcapacitor.community.stripe.terminal;
|
|
2
|
+
|
|
3
|
+
import android.Manifest;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
import androidx.annotation.RequiresApi;
|
|
6
|
+
import com.getcapacitor.PermissionState;
|
|
7
|
+
import com.getcapacitor.Plugin;
|
|
8
|
+
import com.getcapacitor.PluginCall;
|
|
9
|
+
import com.getcapacitor.PluginMethod;
|
|
10
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
11
|
+
import com.getcapacitor.annotation.Permission;
|
|
12
|
+
import com.getcapacitor.annotation.PermissionCallback;
|
|
13
|
+
import com.stripe.stripeterminal.external.models.TerminalException;
|
|
14
|
+
import java.util.Objects;
|
|
15
|
+
import org.json.JSONException;
|
|
16
|
+
|
|
17
|
+
@RequiresApi(api = Build.VERSION_CODES.S)
|
|
18
|
+
@CapacitorPlugin(
|
|
19
|
+
name = "StripeTerminal",
|
|
20
|
+
permissions = {
|
|
21
|
+
@Permission(alias = "location", strings = { Manifest.permission.ACCESS_FINE_LOCATION }),
|
|
22
|
+
@Permission(
|
|
23
|
+
alias = "bluetooth",
|
|
24
|
+
strings = {
|
|
25
|
+
Manifest.permission.BLUETOOTH,
|
|
26
|
+
Manifest.permission.BLUETOOTH_ADMIN,
|
|
27
|
+
Manifest.permission.BLUETOOTH_SCAN,
|
|
28
|
+
Manifest.permission.BLUETOOTH_ADVERTISE,
|
|
29
|
+
Manifest.permission.BLUETOOTH_CONNECT
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
public class StripeTerminalPlugin extends Plugin {
|
|
35
|
+
|
|
36
|
+
private final StripeTerminal implementation = new StripeTerminal(
|
|
37
|
+
this::getContext,
|
|
38
|
+
this::getActivity,
|
|
39
|
+
this::notifyListeners,
|
|
40
|
+
getLogTag()
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
@PluginMethod
|
|
44
|
+
public void initialize(PluginCall call) throws TerminalException {
|
|
45
|
+
this._initialize(call);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@PermissionCallback
|
|
49
|
+
private void locationPermsCallback(PluginCall call) throws TerminalException {
|
|
50
|
+
if (getPermissionState("location") == PermissionState.GRANTED) {
|
|
51
|
+
this._initialize(call);
|
|
52
|
+
} else {
|
|
53
|
+
call.reject("Permission is required to get location");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@PermissionCallback
|
|
58
|
+
private void bluetoothPermsCallback(PluginCall call) throws TerminalException {
|
|
59
|
+
if (getPermissionState("bluetooth") == PermissionState.GRANTED) {
|
|
60
|
+
this._initialize(call);
|
|
61
|
+
} else {
|
|
62
|
+
call.reject("Permission is required to get bluetooth");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private void _initialize(PluginCall call) throws TerminalException {
|
|
67
|
+
if (getPermissionState("location") != PermissionState.GRANTED) {
|
|
68
|
+
requestPermissionForAlias("location", call, "locationPermsCallback");
|
|
69
|
+
} else if (getPermissionState("bluetooth") != PermissionState.GRANTED) {
|
|
70
|
+
requestPermissionForAlias("bluetooth", call, "bluetoothPermsCallback");
|
|
71
|
+
} else {
|
|
72
|
+
this.implementation.initialize(call);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@PluginMethod
|
|
77
|
+
public void discoverReaders(PluginCall call) {
|
|
78
|
+
if (!Objects.equals(call.getString("type"), "tap-to-pay")) {
|
|
79
|
+
call.unimplemented();
|
|
80
|
+
}
|
|
81
|
+
this.implementation.onDiscoverReaders(call);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@PluginMethod
|
|
85
|
+
public void connectReader(PluginCall call) {
|
|
86
|
+
this.implementation.connectReader(call);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@PluginMethod
|
|
90
|
+
public void collect(PluginCall call) {
|
|
91
|
+
this.implementation.collect(call);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package com.getcapacitor.community.stripe.terminal;
|
|
2
|
+
|
|
3
|
+
enum class TerminalEnumEvent(val webEventName: String) {
|
|
4
|
+
Loaded("terminalLoaded"),
|
|
5
|
+
DiscoveredReaders("terminalDiscoveredReaders"),
|
|
6
|
+
ConnectedReader("terminalConnectedReader"),
|
|
7
|
+
Completed("terminalCompleted"),
|
|
8
|
+
Canceled("terminalCanceled"),
|
|
9
|
+
Failed("terminalFailed"),
|
|
10
|
+
}
|