capacitor-microblink 0.0.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapacitorMicroblink.podspec +1 -0
- package/LICENSE +21 -0
- package/Package.swift +3 -2
- package/README.md +65 -42
- package/android/build.gradle +10 -1
- package/android/src/main/java/com/otto/microblink/BlinkCardInitBridge.kt +29 -0
- package/android/src/main/java/com/otto/microblink/MicroblinkPlugin.java +174 -163
- package/dist/docs.json +126 -78
- package/dist/esm/definitions.d.ts +36 -24
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -2
- package/dist/esm/web.js +5 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +5 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +5 -2
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/MicroblinkPlugin/MicroblinkPlugin.swift +171 -123
- package/package.json +2 -2
|
@@ -1,213 +1,224 @@
|
|
|
1
1
|
package com.otto.microblink;
|
|
2
2
|
|
|
3
|
+
import android.content.Intent;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
|
|
6
|
+
import androidx.activity.result.ActivityResult;
|
|
7
|
+
|
|
3
8
|
import com.getcapacitor.JSObject;
|
|
4
9
|
import com.getcapacitor.Plugin;
|
|
5
10
|
import com.getcapacitor.PluginCall;
|
|
6
11
|
import com.getcapacitor.PluginMethod;
|
|
12
|
+
import com.getcapacitor.annotation.ActivityCallback;
|
|
7
13
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
8
|
-
import com.microblink.
|
|
9
|
-
import com.microblink.
|
|
10
|
-
import com.microblink.
|
|
11
|
-
import com.microblink.
|
|
12
|
-
import com.microblink.
|
|
13
|
-
import com.microblink.
|
|
14
|
-
import com.microblink.
|
|
15
|
-
import com.microblink.
|
|
16
|
-
import com.microblink.
|
|
17
|
-
import com.microblink.
|
|
18
|
-
import com.microblink.
|
|
19
|
-
|
|
20
|
-
import
|
|
21
|
-
|
|
22
|
-
import java.util.HashMap;
|
|
23
|
-
import java.util.Iterator;
|
|
24
|
-
import java.util.Map;
|
|
14
|
+
import com.microblink.blinkcard.core.BlinkCardSdkSettings;
|
|
15
|
+
import com.microblink.blinkcard.core.result.CardAccountResult;
|
|
16
|
+
import com.microblink.blinkcard.core.result.DateResult;
|
|
17
|
+
import com.microblink.blinkcard.core.session.BlinkCardScanningResult;
|
|
18
|
+
import com.microblink.blinkcard.core.session.BlinkCardSessionSettings;
|
|
19
|
+
import com.microblink.blinkcard.core.settings.ExtractionSettings;
|
|
20
|
+
import com.microblink.blinkcard.core.settings.ScanningSettings;
|
|
21
|
+
import com.microblink.blinkcard.ux.contract.BlinkCardScanActivityResult;
|
|
22
|
+
import com.microblink.blinkcard.ux.contract.BlinkCardScanActivitySettings;
|
|
23
|
+
import com.microblink.blinkcard.ux.contract.MbBlinkCardScan;
|
|
24
|
+
import com.microblink.blinkcard.ux.contract.ScanActivityResultStatus;
|
|
25
|
+
|
|
26
|
+
import java.util.List;
|
|
27
|
+
import java.util.function.Consumer;
|
|
25
28
|
|
|
26
29
|
@CapacitorPlugin(name = "Microblink")
|
|
27
30
|
public class MicroblinkPlugin extends Plugin {
|
|
28
31
|
|
|
29
|
-
private
|
|
30
|
-
private
|
|
32
|
+
private boolean isBlinkCardInitialized;
|
|
33
|
+
private String blinkCardLicenseKey;
|
|
34
|
+
private String blinkCardLicensee;
|
|
31
35
|
|
|
32
36
|
@PluginMethod
|
|
33
|
-
public void
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
public void scanCard(PluginCall call) {
|
|
38
|
+
String providedLicenseKey = normalized(call.getString("licenseKey"));
|
|
39
|
+
String providedLicensee = normalized(call.getString("licensee"));
|
|
40
|
+
|
|
41
|
+
if (providedLicenseKey != null) {
|
|
42
|
+
initializeBlinkCardLicense(providedLicenseKey, providedLicensee, errorMessage -> {
|
|
43
|
+
if (errorMessage != null) {
|
|
44
|
+
call.reject(errorMessage);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
startBlinkCardScan(call, providedLicenseKey, providedLicensee);
|
|
48
|
+
});
|
|
36
49
|
return;
|
|
37
50
|
}
|
|
38
51
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
String userId = call.getString("userId");
|
|
42
|
-
Boolean isProcessingStoringAllowed = call.getBoolean("isProcessingStoringAllowed");
|
|
43
|
-
Boolean isTrainingAllowed = call.getBoolean("isTrainingAllowed");
|
|
44
|
-
String note = call.getString("note", "");
|
|
45
|
-
Long givenOn = call.getLong("givenOn", System.currentTimeMillis());
|
|
46
|
-
|
|
47
|
-
if (workflowId == null || workflowId.isEmpty()) {
|
|
48
|
-
call.reject("Missing required field: workflowId.");
|
|
52
|
+
if (!isBlinkCardInitialized || blinkCardLicenseKey == null) {
|
|
53
|
+
call.reject("BlinkCard is not initialized. Call initializeBlinkCard first or provide licenseKey in scanCard.");
|
|
49
54
|
return;
|
|
50
55
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
call.reject("Missing required field: isProcessingStoringAllowed.");
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (isTrainingAllowed == null) {
|
|
64
|
-
call.reject("Missing required field: isTrainingAllowed.");
|
|
56
|
+
|
|
57
|
+
startBlinkCardScan(call, blinkCardLicenseKey, blinkCardLicensee);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@PluginMethod
|
|
61
|
+
public void initializeBlinkCard(PluginCall call) {
|
|
62
|
+
String licenseKey = normalized(call.getString("licenseKey"));
|
|
63
|
+
if (licenseKey == null) {
|
|
64
|
+
call.reject("Missing required field: licenseKey.");
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
givenOn
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
Map<String, String> additionalHeaders = new HashMap<>();
|
|
77
|
-
JSObject headersObject = call.getObject("additionalRequestHeaders");
|
|
78
|
-
if (headersObject != null) {
|
|
79
|
-
Iterator<String> keys = headersObject.keys();
|
|
80
|
-
while (keys.hasNext()) {
|
|
81
|
-
String key = keys.next();
|
|
82
|
-
try {
|
|
83
|
-
Object rawValue = headersObject.get(key);
|
|
84
|
-
if (rawValue != null) {
|
|
85
|
-
additionalHeaders.put(key, String.valueOf(rawValue));
|
|
86
|
-
}
|
|
87
|
-
} catch (JSONException ignored) {
|
|
88
|
-
// Ignore malformed header value.
|
|
89
|
-
}
|
|
68
|
+
String licensee = normalized(call.getString("licensee"));
|
|
69
|
+
initializeBlinkCardLicense(licenseKey, licensee, errorMessage -> {
|
|
70
|
+
if (errorMessage != null) {
|
|
71
|
+
call.reject(errorMessage);
|
|
72
|
+
return;
|
|
90
73
|
}
|
|
74
|
+
|
|
75
|
+
JSObject payload = new JSObject();
|
|
76
|
+
payload.put("initialized", true);
|
|
77
|
+
call.resolve(payload);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private void startBlinkCardScan(PluginCall call, String licenseKey, String licensee) {
|
|
82
|
+
if (getContext() == null) {
|
|
83
|
+
call.reject("Unable to start BlinkCard scan: Context is unavailable.");
|
|
84
|
+
return;
|
|
91
85
|
}
|
|
92
86
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
ExtractionSettings extractionSettings = new ExtractionSettings(
|
|
88
|
+
call.getBoolean("extractIban", true),
|
|
89
|
+
call.getBoolean("extractExpiryDate", true),
|
|
90
|
+
call.getBoolean("extractOwner", true),
|
|
91
|
+
call.getBoolean("extractCvv", true),
|
|
92
|
+
call.getBoolean("allowInvalidCardNumber", false)
|
|
93
|
+
);
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
ScanningSettings baseScanningSettings = new ScanningSettings();
|
|
96
|
+
ScanningSettings scanningSettings = baseScanningSettings.copy(
|
|
97
|
+
baseScanningSettings.getSkipImagesWithBlur(),
|
|
98
|
+
baseScanningSettings.getTiltDetectionLevel(),
|
|
99
|
+
baseScanningSettings.getInputImageMargin(),
|
|
100
|
+
extractionSettings,
|
|
101
|
+
baseScanningSettings.getCroppedImageSettings(),
|
|
102
|
+
baseScanningSettings.getLivenessSettings(),
|
|
103
|
+
baseScanningSettings.getAnonymizationSettings()
|
|
103
104
|
);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
|
|
106
|
+
BlinkCardSessionSettings baseSessionSettings = new BlinkCardSessionSettings();
|
|
107
|
+
BlinkCardSessionSettings sessionSettings = baseSessionSettings.copy(
|
|
108
|
+
baseSessionSettings.getInputImageSource(),
|
|
109
|
+
scanningSettings
|
|
108
110
|
);
|
|
109
|
-
MicroblinkPlatformUiSettings uiSettings = new MicroblinkPlatformUiSettings();
|
|
110
|
-
|
|
111
|
-
MicroblinkPlatformResultListener resultListener = new MicroblinkPlatformResultListener() {
|
|
112
|
-
@Override
|
|
113
|
-
public void onVerificationFinished(MicroblinkPlatformResult result) {
|
|
114
|
-
JSObject payload = new JSObject();
|
|
115
|
-
payload.put("canceled", false);
|
|
116
|
-
payload.put("transactionId", result.getTransactionId());
|
|
117
|
-
payload.put("status", toResultStatus(result.getState()));
|
|
118
|
-
if (pendingCardScanResult != null) {
|
|
119
|
-
payload.put("cardScanResult", pendingCardScanResult);
|
|
120
|
-
}
|
|
121
|
-
resolvePending(payload);
|
|
122
|
-
}
|
|
123
111
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
payload.put("canceled", true);
|
|
128
|
-
payload.put("transactionId", cancelState.getTransactionId());
|
|
129
|
-
payload.put("cancelReason", toCancelReason(cancelState.getCancelReason()));
|
|
130
|
-
if (pendingCardScanResult != null) {
|
|
131
|
-
payload.put("cardScanResult", pendingCardScanResult);
|
|
132
|
-
}
|
|
133
|
-
resolvePending(payload);
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
MicroblinkPlatformCardScanResultListener cardScanResultListener = new MicroblinkPlatformCardScanResultListener() {
|
|
138
|
-
@Override
|
|
139
|
-
public void onCardScanned(CardScanResult cardResult) {
|
|
140
|
-
JSObject cardScan = new JSObject();
|
|
141
|
-
cardScan.put("cardNumber", cardResult.getCardNumber());
|
|
142
|
-
cardScan.put("expiryDate", formatExpiry(cardResult));
|
|
143
|
-
cardScan.put("owner", cardResult.getOwner());
|
|
144
|
-
cardScan.put("cvv", cardResult.getCvv());
|
|
145
|
-
pendingCardScanResult = cardScan;
|
|
146
|
-
}
|
|
147
|
-
};
|
|
112
|
+
BlinkCardSdkSettings sdkSettings = licensee == null
|
|
113
|
+
? new BlinkCardSdkSettings(licenseKey)
|
|
114
|
+
: new BlinkCardSdkSettings(licenseKey, licensee);
|
|
148
115
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
);
|
|
116
|
+
BlinkCardScanActivitySettings activitySettings = new BlinkCardScanActivitySettings(sdkSettings, sessionSettings);
|
|
117
|
+
MbBlinkCardScan scanContract = new MbBlinkCardScan();
|
|
118
|
+
Intent scanIntent = scanContract.createIntent(getContext(), activitySettings);
|
|
119
|
+
startActivityForResult(call, scanIntent, "handleBlinkCardScanResult");
|
|
120
|
+
}
|
|
155
121
|
|
|
156
|
-
|
|
157
|
-
|
|
122
|
+
@ActivityCallback
|
|
123
|
+
private void handleBlinkCardScanResult(PluginCall call, ActivityResult activityResult) {
|
|
124
|
+
MbBlinkCardScan scanContract = new MbBlinkCardScan();
|
|
125
|
+
BlinkCardScanActivityResult scanResult = scanContract.parseResult(
|
|
126
|
+
activityResult.getResultCode(),
|
|
127
|
+
activityResult.getData()
|
|
128
|
+
);
|
|
158
129
|
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
call.reject("Unable to start verification: Activity is unavailable.");
|
|
130
|
+
if (scanResult == null) {
|
|
131
|
+
call.reject("BlinkCard scan did not return any result data.");
|
|
162
132
|
return;
|
|
163
133
|
}
|
|
164
134
|
|
|
165
|
-
|
|
166
|
-
|
|
135
|
+
ScanActivityResultStatus status = scanResult.getStatus();
|
|
136
|
+
if (status == ScanActivityResultStatus.Canceled) {
|
|
137
|
+
JSObject payload = new JSObject();
|
|
138
|
+
payload.put("canceled", true);
|
|
139
|
+
call.resolve(payload);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
167
142
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return
|
|
143
|
+
if (status == ScanActivityResultStatus.ErrorSdkInit) {
|
|
144
|
+
call.reject("BlinkCard scan failed because SDK initialization in scan activity failed.");
|
|
145
|
+
return;
|
|
171
146
|
}
|
|
172
|
-
|
|
173
|
-
|
|
147
|
+
|
|
148
|
+
BlinkCardScanningResult result = scanResult.getResult();
|
|
149
|
+
if (result == null) {
|
|
150
|
+
call.reject("BlinkCard scan finished without scan result.");
|
|
151
|
+
return;
|
|
174
152
|
}
|
|
175
|
-
return "review";
|
|
176
|
-
}
|
|
177
153
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
154
|
+
JSObject payload = new JSObject();
|
|
155
|
+
payload.put("canceled", false);
|
|
156
|
+
payload.put("resultState", "valid");
|
|
157
|
+
payload.put("processingStatus", "success");
|
|
158
|
+
payload.put("owner", result.getCardholderName());
|
|
159
|
+
payload.put("iban", result.getIban());
|
|
160
|
+
|
|
161
|
+
List<CardAccountResult> cardAccounts = result.getCardAccounts();
|
|
162
|
+
if (cardAccounts != null && !cardAccounts.isEmpty()) {
|
|
163
|
+
CardAccountResult primaryAccount = null;
|
|
164
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
|
165
|
+
primaryAccount = cardAccounts.getFirst();
|
|
166
|
+
payload.put("cardNumber", primaryAccount.getCardNumber());
|
|
167
|
+
payload.put("cardNumberValid", primaryAccount.getCardNumberValid());
|
|
168
|
+
payload.put("cardNumberPrefix", primaryAccount.getCardNumberPrefix());
|
|
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
|
+
|
|
181
180
|
}
|
|
182
|
-
|
|
181
|
+
|
|
182
|
+
call.resolve(payload);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
private
|
|
186
|
-
if (
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
Integer month = cardResult.getExpiryDate().getMonth();
|
|
190
|
-
Integer year = cardResult.getExpiryDate().getYear();
|
|
191
|
-
if (month == null && year == null) {
|
|
192
|
-
return "";
|
|
185
|
+
private JSObject toBlinkCardDate(DateResult<String> dateResult) {
|
|
186
|
+
if (dateResult == null || dateResult.getDay() == null || dateResult.getMonth() == null || dateResult.getYear() == null) {
|
|
187
|
+
return null;
|
|
193
188
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
189
|
+
|
|
190
|
+
JSObject date = new JSObject();
|
|
191
|
+
date.put("day", dateResult.getDay());
|
|
192
|
+
date.put("month", dateResult.getMonth());
|
|
193
|
+
date.put("year", dateResult.getYear());
|
|
194
|
+
return date;
|
|
197
195
|
}
|
|
198
196
|
|
|
199
|
-
private
|
|
200
|
-
if (
|
|
201
|
-
|
|
197
|
+
private void initializeBlinkCardLicense(String licenseKey, String licensee, Consumer<String> callback) {
|
|
198
|
+
if (getContext() == null) {
|
|
199
|
+
callback.accept("Unable to initialize BlinkCard SDK: Context is unavailable.");
|
|
202
200
|
return;
|
|
203
201
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
202
|
+
|
|
203
|
+
BlinkCardInitBridge.initialize(getContext(), licenseKey, licensee, error -> {
|
|
204
|
+
if (error != null) {
|
|
205
|
+
isBlinkCardInitialized = false;
|
|
206
|
+
callback.accept("Init failed: " + error.getMessage());
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
isBlinkCardInitialized = true;
|
|
211
|
+
blinkCardLicenseKey = licenseKey;
|
|
212
|
+
blinkCardLicensee = licensee;
|
|
213
|
+
callback.accept(null);
|
|
214
|
+
return null;
|
|
215
|
+
});
|
|
207
216
|
}
|
|
208
217
|
|
|
209
|
-
private
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
private String normalized(String value) {
|
|
219
|
+
if (value == null || value.isEmpty()) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return value;
|
|
212
223
|
}
|
|
213
224
|
}
|