capacitor-microblink 0.3.0 → 0.3.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/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 +92 -23
- package/dist/docs.json +28 -0
- package/dist/esm/definitions.d.ts +7 -0
- 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 +42 -1
- 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,23 +236,12 @@ 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);
|
|
@@ -216,9 +281,13 @@ public class MicroblinkPlugin extends Plugin {
|
|
|
216
281
|
}
|
|
217
282
|
|
|
218
283
|
private String normalized(String value) {
|
|
219
|
-
if (value == null
|
|
284
|
+
if (value == null) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
String trimmed = value.trim();
|
|
288
|
+
if (trimmed.isEmpty()) {
|
|
220
289
|
return null;
|
|
221
290
|
}
|
|
222
|
-
return
|
|
291
|
+
return trimmed;
|
|
223
292
|
}
|
|
224
293
|
}
|
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": []
|
|
@@ -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": [],
|
|
@@ -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: 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 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"]}
|
|
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,
|