capacitor-microblink 0.3.0 → 0.4.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/README.md +46 -0
- package/android/build.gradle +5 -3
- package/android/src/main/java/com/otto/microblink/BlinkCardInitBridge.kt +38 -4
- package/android/src/main/java/com/otto/microblink/MicroblinkPlugin.java +98 -25
- package/dist/docs.json +29 -1
- package/dist/esm/definitions.d.ts +8 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -1
- package/dist/esm/web.js +3 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +3 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/MicroblinkPlugin/MicroblinkPlugin.swift +50 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,12 +9,38 @@ npm install capacitor-microblink
|
|
|
9
9
|
npx cap sync
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
### Android Auto Init (on app startup)
|
|
13
|
+
|
|
14
|
+
If you want `initializeBlinkCard` to run automatically during Android plugin load (`onCreate` phase), set plugin config values:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// capacitor.config.ts
|
|
18
|
+
plugins: {
|
|
19
|
+
Microblink: {
|
|
20
|
+
licenseKey: 'YOUR_BLINKCARD_LICENSE_KEY',
|
|
21
|
+
licensee: 'OPTIONAL_LICENSEE',
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### iOS Camera Permission
|
|
27
|
+
|
|
28
|
+
BlinkCard scanning requires camera access on iOS.
|
|
29
|
+
|
|
30
|
+
Add this key to your app `Info.plist`:
|
|
31
|
+
|
|
32
|
+
```xml
|
|
33
|
+
<key>NSCameraUsageDescription</key>
|
|
34
|
+
<string>We need camera access to scan your card.</string>
|
|
35
|
+
```
|
|
36
|
+
|
|
12
37
|
## API
|
|
13
38
|
|
|
14
39
|
<docgen-index>
|
|
15
40
|
|
|
16
41
|
* [`scanCard(...)`](#scancard)
|
|
17
42
|
* [`initializeBlinkCard(...)`](#initializeblinkcard)
|
|
43
|
+
* [`terminateBlinkCard()`](#terminateblinkcard)
|
|
18
44
|
* [Interfaces](#interfaces)
|
|
19
45
|
|
|
20
46
|
</docgen-index>
|
|
@@ -56,6 +82,19 @@ Initializes BlinkCard SDK/license before scanning.
|
|
|
56
82
|
--------------------
|
|
57
83
|
|
|
58
84
|
|
|
85
|
+
### terminateBlinkCard()
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
terminateBlinkCard() => Promise<TerminateBlinkCardResult>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Terminates BlinkCard SDK and clears cached plugin initialization state.
|
|
92
|
+
|
|
93
|
+
**Returns:** <code>Promise<<a href="#terminateblinkcardresult">TerminateBlinkCardResult</a>></code>
|
|
94
|
+
|
|
95
|
+
--------------------
|
|
96
|
+
|
|
97
|
+
|
|
59
98
|
### Interfaces
|
|
60
99
|
|
|
61
100
|
|
|
@@ -112,4 +151,11 @@ Initializes BlinkCard SDK/license before scanning.
|
|
|
112
151
|
| **`licenseKey`** | <code>string</code> |
|
|
113
152
|
| **`licensee`** | <code>string</code> |
|
|
114
153
|
|
|
154
|
+
|
|
155
|
+
#### TerminateBlinkCardResult
|
|
156
|
+
|
|
157
|
+
| Prop | Type |
|
|
158
|
+
| ---------------- | -------------------- |
|
|
159
|
+
| **`terminated`** | <code>boolean</code> |
|
|
160
|
+
|
|
115
161
|
</docgen-api>
|
package/android/build.gradle
CHANGED
|
@@ -23,6 +23,8 @@ buildscript {
|
|
|
23
23
|
apply plugin: 'com.android.library'
|
|
24
24
|
apply plugin: 'org.jetbrains.kotlin.android'
|
|
25
25
|
|
|
26
|
+
def jvmTargetVersion = project.hasProperty('jvmTargetVersion') ? project.property('jvmTargetVersion') : '17'
|
|
27
|
+
|
|
26
28
|
android {
|
|
27
29
|
namespace = "com.otto.microblink"
|
|
28
30
|
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
|
|
@@ -45,11 +47,11 @@ android {
|
|
|
45
47
|
disable += ["Aligned16KB"]
|
|
46
48
|
}
|
|
47
49
|
compileOptions {
|
|
48
|
-
sourceCompatibility JavaVersion.
|
|
49
|
-
targetCompatibility JavaVersion.
|
|
50
|
+
sourceCompatibility JavaVersion.toVersion(jvmTargetVersion)
|
|
51
|
+
targetCompatibility JavaVersion.toVersion(jvmTargetVersion)
|
|
50
52
|
}
|
|
51
53
|
kotlinOptions {
|
|
52
|
-
jvmTarget =
|
|
54
|
+
jvmTarget = jvmTargetVersion
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -8,6 +8,18 @@ import kotlinx.coroutines.Dispatchers
|
|
|
8
8
|
import kotlinx.coroutines.launch
|
|
9
9
|
|
|
10
10
|
object BlinkCardInitBridge {
|
|
11
|
+
private fun resetSdkInstance() {
|
|
12
|
+
try {
|
|
13
|
+
val sdkField = BlinkCardSdk::class.java.getDeclaredField("sdkInstance")
|
|
14
|
+
sdkField.isAccessible = true
|
|
15
|
+
val existingSdk = sdkField.get(null) as? BlinkCardSdk
|
|
16
|
+
existingSdk?.close()
|
|
17
|
+
sdkField.set(null, null)
|
|
18
|
+
} catch (_: Throwable) {
|
|
19
|
+
// Best-effort reset. If reflection fails, initialization may still succeed.
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
11
23
|
@JvmStatic
|
|
12
24
|
fun initialize(
|
|
13
25
|
context: Context,
|
|
@@ -16,14 +28,36 @@ object BlinkCardInitBridge {
|
|
|
16
28
|
callback: (Throwable?) -> Unit
|
|
17
29
|
) {
|
|
18
30
|
CoroutineScope(Dispatchers.Main).launch {
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
resetSdkInstance()
|
|
32
|
+
val normalizedLicenseKey = licenseKey.trim()
|
|
33
|
+
val normalizedLicensee = licensee?.trim()?.takeIf { it.isNotEmpty() }
|
|
34
|
+
val settings = if (normalizedLicensee != null) {
|
|
35
|
+
BlinkCardSdkSettings(
|
|
36
|
+
licenseKey = normalizedLicenseKey,
|
|
37
|
+
licensee = normalizedLicensee
|
|
38
|
+
)
|
|
39
|
+
} else {
|
|
21
40
|
BlinkCardSdkSettings(
|
|
22
|
-
licenseKey =
|
|
23
|
-
licensee = licensee ?: ""
|
|
41
|
+
licenseKey = normalizedLicenseKey
|
|
24
42
|
)
|
|
43
|
+
}
|
|
44
|
+
val result = BlinkCardSdk.initializeSdk(
|
|
45
|
+
context.applicationContext,
|
|
46
|
+
settings
|
|
25
47
|
)
|
|
26
48
|
callback(result.exceptionOrNull())
|
|
27
49
|
}
|
|
28
50
|
}
|
|
51
|
+
|
|
52
|
+
@JvmStatic
|
|
53
|
+
fun terminate(callback: (Throwable?) -> Unit) {
|
|
54
|
+
CoroutineScope(Dispatchers.Main).launch {
|
|
55
|
+
try {
|
|
56
|
+
resetSdkInstance()
|
|
57
|
+
callback(null)
|
|
58
|
+
} catch (error: Throwable) {
|
|
59
|
+
callback(error)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
29
63
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
package com.otto.microblink;
|
|
2
2
|
|
|
3
|
+
import android.Manifest;
|
|
3
4
|
import android.content.Intent;
|
|
4
|
-
import android.
|
|
5
|
-
|
|
5
|
+
import android.util.Log;
|
|
6
6
|
import androidx.activity.result.ActivityResult;
|
|
7
7
|
|
|
8
8
|
import com.getcapacitor.JSObject;
|
|
9
|
+
import com.getcapacitor.PermissionState;
|
|
9
10
|
import com.getcapacitor.Plugin;
|
|
10
11
|
import com.getcapacitor.PluginCall;
|
|
11
12
|
import com.getcapacitor.PluginMethod;
|
|
12
13
|
import com.getcapacitor.annotation.ActivityCallback;
|
|
13
14
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
15
|
+
import com.getcapacitor.annotation.Permission;
|
|
14
16
|
import com.microblink.blinkcard.core.BlinkCardSdkSettings;
|
|
15
17
|
import com.microblink.blinkcard.core.result.CardAccountResult;
|
|
16
18
|
import com.microblink.blinkcard.core.result.DateResult;
|
|
@@ -26,15 +28,63 @@ import com.microblink.blinkcard.ux.contract.ScanActivityResultStatus;
|
|
|
26
28
|
import java.util.List;
|
|
27
29
|
import java.util.function.Consumer;
|
|
28
30
|
|
|
29
|
-
@CapacitorPlugin(
|
|
31
|
+
@CapacitorPlugin(
|
|
32
|
+
name = "Microblink",
|
|
33
|
+
permissions = {
|
|
34
|
+
@Permission(alias = "camera", strings = { Manifest.permission.CAMERA })
|
|
35
|
+
}
|
|
36
|
+
)
|
|
30
37
|
public class MicroblinkPlugin extends Plugin {
|
|
38
|
+
private static final String TAG = "MicroblinkPlugin";
|
|
31
39
|
|
|
32
40
|
private boolean isBlinkCardInitialized;
|
|
33
41
|
private String blinkCardLicenseKey;
|
|
34
42
|
private String blinkCardLicensee;
|
|
35
43
|
|
|
44
|
+
@Override
|
|
45
|
+
public void load() {
|
|
46
|
+
super.load();
|
|
47
|
+
|
|
48
|
+
String configuredLicenseKey = normalized(getConfig().getString("licenseKey"));
|
|
49
|
+
if (configuredLicenseKey == null) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
String configuredLicensee = normalized(getConfig().getString("licensee"));
|
|
54
|
+
initializeBlinkCardLicense(configuredLicenseKey, configuredLicensee, errorMessage -> {
|
|
55
|
+
if (errorMessage != null) {
|
|
56
|
+
Log.w(TAG, "Auto initializeBlinkCard on load failed: " + errorMessage);
|
|
57
|
+
} else {
|
|
58
|
+
Log.i(TAG, "BlinkCard auto-initialized from plugin config.");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
36
63
|
@PluginMethod
|
|
37
64
|
public void scanCard(PluginCall call) {
|
|
65
|
+
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
66
|
+
requestPermissionForAlias("camera", call, "cameraPermissionCallback");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
performScanCard(call);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@com.getcapacitor.annotation.PermissionCallback
|
|
74
|
+
private void cameraPermissionCallback(PluginCall call) {
|
|
75
|
+
if (call == null) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (getPermissionState("camera") != PermissionState.GRANTED) {
|
|
80
|
+
call.reject("Camera permission is required to scan cards.");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
performScanCard(call);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private void performScanCard(PluginCall call) {
|
|
38
88
|
String providedLicenseKey = normalized(call.getString("licenseKey"));
|
|
39
89
|
String providedLicensee = normalized(call.getString("licensee"));
|
|
40
90
|
|
|
@@ -54,7 +104,13 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
54
104
|
return;
|
|
55
105
|
}
|
|
56
106
|
|
|
57
|
-
|
|
107
|
+
initializeBlinkCardLicense(blinkCardLicenseKey, blinkCardLicensee, errorMessage -> {
|
|
108
|
+
if (errorMessage != null) {
|
|
109
|
+
call.reject(errorMessage);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
startBlinkCardScan(call, blinkCardLicenseKey, blinkCardLicensee);
|
|
113
|
+
});
|
|
58
114
|
}
|
|
59
115
|
|
|
60
116
|
@PluginMethod
|
|
@@ -78,6 +134,25 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
78
134
|
});
|
|
79
135
|
}
|
|
80
136
|
|
|
137
|
+
@PluginMethod
|
|
138
|
+
public void terminateBlinkCard(PluginCall call) {
|
|
139
|
+
BlinkCardInitBridge.terminate(error -> {
|
|
140
|
+
if (error != null) {
|
|
141
|
+
call.reject("Failed to terminate BlinkCard SDK: " + error.getMessage());
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
isBlinkCardInitialized = false;
|
|
146
|
+
blinkCardLicenseKey = null;
|
|
147
|
+
blinkCardLicensee = null;
|
|
148
|
+
|
|
149
|
+
JSObject payload = new JSObject();
|
|
150
|
+
payload.put("terminated", true);
|
|
151
|
+
call.resolve(payload);
|
|
152
|
+
return null;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
81
156
|
private void startBlinkCardScan(PluginCall call, String licenseKey, String licensee) {
|
|
82
157
|
if (getContext() == null) {
|
|
83
158
|
call.reject("Unable to start BlinkCard scan: Context is unavailable.");
|
|
@@ -141,6 +216,7 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
141
216
|
}
|
|
142
217
|
|
|
143
218
|
if (status == ScanActivityResultStatus.ErrorSdkInit) {
|
|
219
|
+
isBlinkCardInitialized = false;
|
|
144
220
|
call.reject("BlinkCard scan failed because SDK initialization in scan activity failed.");
|
|
145
221
|
return;
|
|
146
222
|
}
|
|
@@ -160,37 +236,30 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
160
236
|
|
|
161
237
|
List<CardAccountResult> cardAccounts = result.getCardAccounts();
|
|
162
238
|
if (cardAccounts != null && !cardAccounts.isEmpty()) {
|
|
163
|
-
CardAccountResult primaryAccount =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
payload.put("cvv", primaryAccount.getCvv());
|
|
170
|
-
payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
|
|
171
|
-
} else {
|
|
172
|
-
primaryAccount = cardAccounts.get(0);
|
|
173
|
-
payload.put("cardNumber", primaryAccount.getCardNumber());
|
|
174
|
-
payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
|
|
175
|
-
payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
|
|
176
|
-
payload.put("cvv", primaryAccount.getCvv());
|
|
177
|
-
payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
|
|
178
|
-
}
|
|
179
|
-
|
|
239
|
+
CardAccountResult primaryAccount = cardAccounts.get(0);
|
|
240
|
+
payload.put("cardNumber", primaryAccount.getCardNumber());
|
|
241
|
+
payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
|
|
242
|
+
payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
|
|
243
|
+
payload.put("cvv", primaryAccount.getCvv());
|
|
244
|
+
payload.put("expiryDate", toBlinkCardDate(primaryAccount.getExpiryDate()));
|
|
180
245
|
}
|
|
181
246
|
|
|
182
247
|
call.resolve(payload);
|
|
183
248
|
}
|
|
184
249
|
|
|
185
250
|
private JSObject toBlinkCardDate(DateResult<String> dateResult) {
|
|
186
|
-
if (dateResult == null || dateResult.
|
|
251
|
+
if (dateResult == null || dateResult.getMonth() == null || dateResult.getYear() == null) {
|
|
187
252
|
return null;
|
|
188
253
|
}
|
|
189
254
|
|
|
190
255
|
JSObject date = new JSObject();
|
|
191
|
-
date.put("day", dateResult.getDay());
|
|
192
256
|
date.put("month", dateResult.getMonth());
|
|
193
257
|
date.put("year", dateResult.getYear());
|
|
258
|
+
|
|
259
|
+
if (dateResult.getDay() != null) {
|
|
260
|
+
date.put("day", dateResult.getDay());
|
|
261
|
+
}
|
|
262
|
+
|
|
194
263
|
return date;
|
|
195
264
|
}
|
|
196
265
|
|
|
@@ -216,9 +285,13 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
216
285
|
}
|
|
217
286
|
|
|
218
287
|
private String normalized(String value) {
|
|
219
|
-
if (value == null
|
|
288
|
+
if (value == null) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
String trimmed = value.trim();
|
|
292
|
+
if (trimmed.isEmpty()) {
|
|
220
293
|
return null;
|
|
221
294
|
}
|
|
222
|
-
return
|
|
295
|
+
return trimmed;
|
|
223
296
|
}
|
|
224
297
|
}
|
package/dist/docs.json
CHANGED
|
@@ -42,6 +42,18 @@
|
|
|
42
42
|
"InitializeBlinkCardOptions"
|
|
43
43
|
],
|
|
44
44
|
"slug": "initializeblinkcard"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "terminateBlinkCard",
|
|
48
|
+
"signature": "() => Promise<TerminateBlinkCardResult>",
|
|
49
|
+
"parameters": [],
|
|
50
|
+
"returns": "Promise<TerminateBlinkCardResult>",
|
|
51
|
+
"tags": [],
|
|
52
|
+
"docs": "Terminates BlinkCard SDK and clears cached plugin initialization state.",
|
|
53
|
+
"complexTypes": [
|
|
54
|
+
"TerminateBlinkCardResult"
|
|
55
|
+
],
|
|
56
|
+
"slug": "terminateblinkcard"
|
|
45
57
|
}
|
|
46
58
|
],
|
|
47
59
|
"properties": []
|
|
@@ -140,7 +152,7 @@
|
|
|
140
152
|
"tags": [],
|
|
141
153
|
"docs": "",
|
|
142
154
|
"complexTypes": [],
|
|
143
|
-
"type": "number"
|
|
155
|
+
"type": "number | undefined"
|
|
144
156
|
},
|
|
145
157
|
{
|
|
146
158
|
"name": "month",
|
|
@@ -261,6 +273,22 @@
|
|
|
261
273
|
"type": "string | undefined"
|
|
262
274
|
}
|
|
263
275
|
]
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"name": "TerminateBlinkCardResult",
|
|
279
|
+
"slug": "terminateblinkcardresult",
|
|
280
|
+
"docs": "",
|
|
281
|
+
"tags": [],
|
|
282
|
+
"methods": [],
|
|
283
|
+
"properties": [
|
|
284
|
+
{
|
|
285
|
+
"name": "terminated",
|
|
286
|
+
"tags": [],
|
|
287
|
+
"docs": "",
|
|
288
|
+
"complexTypes": [],
|
|
289
|
+
"type": "boolean"
|
|
290
|
+
}
|
|
291
|
+
]
|
|
264
292
|
}
|
|
265
293
|
],
|
|
266
294
|
"enums": [],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface BlinkCardDate {
|
|
2
|
-
day
|
|
2
|
+
day?: number;
|
|
3
3
|
month: number;
|
|
4
4
|
year: number;
|
|
5
5
|
}
|
|
@@ -20,6 +20,9 @@ export interface InitializeBlinkCardOptions {
|
|
|
20
20
|
export interface InitializeBlinkCardResult {
|
|
21
21
|
initialized: boolean;
|
|
22
22
|
}
|
|
23
|
+
export interface TerminateBlinkCardResult {
|
|
24
|
+
terminated: boolean;
|
|
25
|
+
}
|
|
23
26
|
export interface ScanCardResult {
|
|
24
27
|
canceled: boolean;
|
|
25
28
|
resultState?: 'empty' | 'uncertain' | 'valid' | 'stageValid';
|
|
@@ -41,4 +44,8 @@ export interface MicroblinkPlugin {
|
|
|
41
44
|
* Initializes BlinkCard SDK/license before scanning.
|
|
42
45
|
*/
|
|
43
46
|
initializeBlinkCard(options: InitializeBlinkCardOptions): Promise<InitializeBlinkCardResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Terminates BlinkCard SDK and clears cached plugin initialization state.
|
|
49
|
+
*/
|
|
50
|
+
terminateBlinkCard(): Promise<TerminateBlinkCardResult>;
|
|
44
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface BlinkCardDate {\n day
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface BlinkCardDate {\n day?: number;\n month: number;\n year: number;\n}\n\nexport interface ScanCardOptions {\n licenseKey?: string;\n licensee?: string;\n extractOwner?: boolean;\n extractExpiryDate?: boolean;\n extractCvv?: boolean;\n extractIban?: boolean;\n allowInvalidCardNumber?: boolean;\n enableEditScreen?: boolean;\n}\n\nexport interface InitializeBlinkCardOptions {\n licenseKey: string;\n licensee?: string;\n}\n\nexport interface InitializeBlinkCardResult {\n initialized: boolean;\n}\n\nexport interface TerminateBlinkCardResult {\n terminated: boolean;\n}\n\nexport interface ScanCardResult {\n canceled: boolean;\n resultState?: 'empty' | 'uncertain' | 'valid' | 'stageValid';\n processingStatus?:\n | 'success'\n | 'detectionFailed'\n | 'imagePreprocessingFailed'\n | 'stabilityTestFailed'\n | 'scanningWrongSide'\n | 'fieldIdentificationFailed'\n | 'imageReturnFailed'\n | 'unsupportedCard';\n cardNumber?: string;\n cardNumberValid?: boolean;\n cardNumberPrefix?: string;\n owner?: string;\n cvv?: string;\n iban?: string;\n expiryDate?: BlinkCardDate | null;\n}\n\nexport interface MicroblinkPlugin {\n /**\n * Starts BlinkCard card scanning flow.\n */\n scanCard(options: ScanCardOptions): Promise<ScanCardResult>;\n\n /**\n * Initializes BlinkCard SDK/license before scanning.\n */\n initializeBlinkCard(\n options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult>;\n\n /**\n * Terminates BlinkCard SDK and clears cached plugin initialization state.\n */\n terminateBlinkCard(): Promise<TerminateBlinkCardResult>;\n}\n"]}
|
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
|
-
import type { InitializeBlinkCardOptions, InitializeBlinkCardResult, MicroblinkPlugin, ScanCardOptions, ScanCardResult } from './definitions';
|
|
2
|
+
import type { InitializeBlinkCardOptions, InitializeBlinkCardResult, MicroblinkPlugin, ScanCardOptions, ScanCardResult, TerminateBlinkCardResult } from './definitions';
|
|
3
3
|
export declare class MicroblinkWeb extends WebPlugin implements MicroblinkPlugin {
|
|
4
4
|
scanCard(_options: ScanCardOptions): Promise<ScanCardResult>;
|
|
5
5
|
initializeBlinkCard(_options: InitializeBlinkCardOptions): Promise<InitializeBlinkCardResult>;
|
|
6
|
+
terminateBlinkCard(): Promise<TerminateBlinkCardResult>;
|
|
6
7
|
}
|
package/dist/esm/web.js
CHANGED
|
@@ -6,5 +6,8 @@ export class MicroblinkWeb extends WebPlugin {
|
|
|
6
6
|
async initializeBlinkCard(_options) {
|
|
7
7
|
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
8
8
|
}
|
|
9
|
+
async terminateBlinkCard() {
|
|
10
|
+
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
11
|
+
}
|
|
9
12
|
}
|
|
10
13
|
//# sourceMappingURL=web.js.map
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAW5C,MAAM,OAAO,aAAc,SAAQ,SAAS;IAC1C,KAAK,CAAC,QAAQ,CAAC,QAAyB;QACtC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,mBAAmB,CACvB,QAAoC;QAEpC,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC,CAAC;IAC9E,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n InitializeBlinkCardOptions,\n InitializeBlinkCardResult,\n MicroblinkPlugin,\n ScanCardOptions,\n ScanCardResult,\n TerminateBlinkCardResult,\n} from './definitions';\n\nexport class MicroblinkWeb extends WebPlugin implements MicroblinkPlugin {\n async scanCard(_options: ScanCardOptions): Promise<ScanCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n\n async initializeBlinkCard(\n _options: InitializeBlinkCardOptions,\n ): Promise<InitializeBlinkCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n\n async terminateBlinkCard(): Promise<TerminateBlinkCardResult> {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n"]}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -13,6 +13,9 @@ class MicroblinkWeb extends core.WebPlugin {
|
|
|
13
13
|
async initializeBlinkCard(_options) {
|
|
14
14
|
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
15
15
|
}
|
|
16
|
+
async terminateBlinkCard() {
|
|
17
|
+
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
var web = /*#__PURE__*/Object.freeze({
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;AAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;AACjE,CAAC;;ACFM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;AAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;AACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async terminateBlinkCard() {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;AAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;AACjE,CAAC;;ACFM,MAAM,aAAa,SAASC,cAAS,CAAC;AAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;AAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;AACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;AACnF,IAAI;AACJ;;;;;;;;;"}
|
package/dist/plugin.js
CHANGED
|
@@ -12,6 +12,9 @@ var capacitorMicroblink = (function (exports, core) {
|
|
|
12
12
|
async initializeBlinkCard(_options) {
|
|
13
13
|
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
14
14
|
}
|
|
15
|
+
async terminateBlinkCard() {
|
|
16
|
+
throw this.unimplemented('BlinkCard is only available on Android and iOS.');
|
|
17
|
+
}
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
var web = /*#__PURE__*/Object.freeze({
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;IAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;IACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Microblink = registerPlugin('Microblink', {\n web: () => import('./web').then((m) => new m.MicroblinkWeb()),\n});\nexport * from './definitions';\nexport { Microblink };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class MicroblinkWeb extends WebPlugin {\n async scanCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async initializeBlinkCard(_options) {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n async terminateBlinkCard() {\n throw this.unimplemented('BlinkCard is only available on Android and iOS.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,UAAU,GAAGA,mBAAc,CAAC,YAAY,EAAE;IAChD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC;;ICFM,MAAM,aAAa,SAASC,cAAS,CAAC;IAC7C,IAAI,MAAM,QAAQ,CAAC,QAAQ,EAAE;IAC7B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,mBAAmB,CAAC,QAAQ,EAAE;IACxC,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,iDAAiD,CAAC;IACnF,IAAI;IACJ;;;;;;;;;;;;;;;"}
|
|
@@ -2,6 +2,7 @@ import Foundation
|
|
|
2
2
|
import Capacitor
|
|
3
3
|
import Combine
|
|
4
4
|
import SwiftUI
|
|
5
|
+
import AVFoundation
|
|
5
6
|
import BlinkCard
|
|
6
7
|
import BlinkCardUX
|
|
7
8
|
|
|
@@ -11,7 +12,8 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
11
12
|
public let jsName = "Microblink"
|
|
12
13
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
13
14
|
CAPPluginMethod(name: "initializeBlinkCard", returnType: CAPPluginReturnPromise),
|
|
14
|
-
CAPPluginMethod(name: "scanCard", returnType: CAPPluginReturnPromise)
|
|
15
|
+
CAPPluginMethod(name: "scanCard", returnType: CAPPluginReturnPromise),
|
|
16
|
+
CAPPluginMethod(name: "terminateBlinkCard", returnType: CAPPluginReturnPromise)
|
|
15
17
|
]
|
|
16
18
|
|
|
17
19
|
private enum PluginError: LocalizedError {
|
|
@@ -58,6 +60,12 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
@objc public func scanCard(_ call: CAPPluginCall) {
|
|
63
|
+
ensureCameraPermission(call) { [weak self] in
|
|
64
|
+
self?.performScanCard(call)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private func performScanCard(_ call: CAPPluginCall) {
|
|
61
69
|
if pendingBlinkCardCallId != nil {
|
|
62
70
|
call.reject("A BlinkCard flow is already running.")
|
|
63
71
|
return
|
|
@@ -100,6 +108,39 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
100
108
|
}
|
|
101
109
|
}
|
|
102
110
|
|
|
111
|
+
private func ensureCameraPermission(_ call: CAPPluginCall, onGranted: @escaping () -> Void) {
|
|
112
|
+
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
|
113
|
+
switch status {
|
|
114
|
+
case .authorized:
|
|
115
|
+
onGranted()
|
|
116
|
+
case .notDetermined:
|
|
117
|
+
AVCaptureDevice.requestAccess(for: .video) { granted in
|
|
118
|
+
DispatchQueue.main.async {
|
|
119
|
+
if granted {
|
|
120
|
+
onGranted()
|
|
121
|
+
} else {
|
|
122
|
+
call.reject("Camera permission is required to scan cards.")
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
case .denied, .restricted:
|
|
127
|
+
call.reject("Camera permission is required to scan cards. Enable it in iOS Settings.")
|
|
128
|
+
@unknown default:
|
|
129
|
+
call.reject("Unable to determine camera permission status.")
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@objc public func terminateBlinkCard(_ call: CAPPluginCall) {
|
|
134
|
+
Task {
|
|
135
|
+
await BlinkCardSdk.terminateBlinkCardSdk()
|
|
136
|
+
await MainActor.run {
|
|
137
|
+
self.blinkCardSdk = nil
|
|
138
|
+
self.isBlinkCardInitialized = false
|
|
139
|
+
call.resolve(["terminated": true])
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
103
144
|
private func startBlinkCardScan(call: CAPPluginCall, sdk: BlinkCardSdk, presentingViewController: UIViewController) async throws {
|
|
104
145
|
let extractionSettings = ExtractionSettings(
|
|
105
146
|
extractIban: call.getBool("extractIban") ?? true,
|
|
@@ -192,16 +233,21 @@ public class MicroblinkPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
192
233
|
|
|
193
234
|
private func mapBlinkCardDate(_ date: DateResult?) -> [String: Int]? {
|
|
194
235
|
guard let date,
|
|
195
|
-
let day = date.day,
|
|
196
236
|
let month = date.month,
|
|
197
237
|
let year = date.year else {
|
|
198
238
|
return nil
|
|
199
239
|
}
|
|
200
|
-
|
|
201
|
-
|
|
240
|
+
|
|
241
|
+
var mappedDate: [String: Int] = [
|
|
202
242
|
"month": month,
|
|
203
243
|
"year": year
|
|
204
244
|
]
|
|
245
|
+
|
|
246
|
+
if let day = date.day {
|
|
247
|
+
mappedDate["day"] = day
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return mappedDate
|
|
205
251
|
}
|
|
206
252
|
|
|
207
253
|
private func createBlinkCardSdk(licenseKey: String, licensee: String?) async throws -> BlinkCardSdk {
|