@flonkid/kyc 1.8.2 → 1.9.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 +109 -3
- package/dist/index.cjs +318 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -4
- package/dist/index.d.ts +128 -4
- package/dist/index.js +313 -14
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +102 -32
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +938 -36
- package/dist/server.d.ts +938 -36
- package/dist/server.js +103 -33
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +950 -34
- package/package.json +78 -49
package/dist/server.d.cts
CHANGED
|
@@ -1,3 +1,865 @@
|
|
|
1
|
+
interface components {
|
|
2
|
+
schemas: {
|
|
3
|
+
CreateSessionRequestDto: {
|
|
4
|
+
/**
|
|
5
|
+
* @description Client identifier for session association (optional)
|
|
6
|
+
* @example client-12345
|
|
7
|
+
*/
|
|
8
|
+
clientId?: string;
|
|
9
|
+
/**
|
|
10
|
+
* @description Client metadata for identification (optional) - arbitrary object with client identifiers
|
|
11
|
+
* @example {
|
|
12
|
+
* "email": "user@example.com",
|
|
13
|
+
* "userId": "12345",
|
|
14
|
+
* "customId": "internal-id"
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
clientMetadata?: Record<string, never>;
|
|
18
|
+
/**
|
|
19
|
+
* @description Document type for verification (required)
|
|
20
|
+
* @example id_card
|
|
21
|
+
* @enum {string}
|
|
22
|
+
*/
|
|
23
|
+
documentType: "passport" | "id_card" | "driver_license";
|
|
24
|
+
/**
|
|
25
|
+
* @description Session lifetime in seconds (optional, default: 300)
|
|
26
|
+
* @default 300
|
|
27
|
+
* @example 300
|
|
28
|
+
*/
|
|
29
|
+
expiresIn: number;
|
|
30
|
+
};
|
|
31
|
+
SessionResponseDto: {
|
|
32
|
+
/**
|
|
33
|
+
* @description Unique session identifier
|
|
34
|
+
* @example clx1234567890abcdef
|
|
35
|
+
*/
|
|
36
|
+
id: string;
|
|
37
|
+
/**
|
|
38
|
+
* @description Session status
|
|
39
|
+
* @example pending
|
|
40
|
+
* @enum {string}
|
|
41
|
+
*/
|
|
42
|
+
status: "pending" | "in_progress" | "completed" | "failed" | "expired";
|
|
43
|
+
/**
|
|
44
|
+
* Format: date-time
|
|
45
|
+
* @description Session expiration timestamp
|
|
46
|
+
* @example 2024-10-25T14:30:00.000Z
|
|
47
|
+
*/
|
|
48
|
+
expiresAt: string;
|
|
49
|
+
/**
|
|
50
|
+
* @description Client metadata
|
|
51
|
+
* @example {
|
|
52
|
+
* "userId": "user_12345",
|
|
53
|
+
* "email": "john.doe@example.com"
|
|
54
|
+
* }
|
|
55
|
+
*/
|
|
56
|
+
clientMetadata?: Record<string, never>;
|
|
57
|
+
/**
|
|
58
|
+
* @description Widget URL for embedding
|
|
59
|
+
* @example https://widget.flonk.id/?sessionId=clx1234567890abcdef&mode=embedded
|
|
60
|
+
*/
|
|
61
|
+
widgetUrl: string;
|
|
62
|
+
/**
|
|
63
|
+
* @description QR code data for mobile verification
|
|
64
|
+
* @example https://widget.flonk.id/verify/clx1234567890abcdef?token=kyc_1234567890_abc123
|
|
65
|
+
*/
|
|
66
|
+
qrCodeUrl: string;
|
|
67
|
+
/**
|
|
68
|
+
* Format: date-time
|
|
69
|
+
* @description Session creation timestamp
|
|
70
|
+
* @example 2024-10-25T14:25:00.000Z
|
|
71
|
+
*/
|
|
72
|
+
createdAt: string;
|
|
73
|
+
/**
|
|
74
|
+
* @description Project identifier
|
|
75
|
+
* @example clxproject123
|
|
76
|
+
*/
|
|
77
|
+
projectId: string;
|
|
78
|
+
/**
|
|
79
|
+
* @description Whether manual upload is allowed for this session
|
|
80
|
+
* @example true
|
|
81
|
+
*/
|
|
82
|
+
allowManualUpload: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* @description Embed token for widget authentication (like Stripe client_secret)
|
|
85
|
+
* @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
86
|
+
*/
|
|
87
|
+
embedToken?: string;
|
|
88
|
+
/**
|
|
89
|
+
* @description Indicates if an existing session was reused instead of creating a new one
|
|
90
|
+
* @example false
|
|
91
|
+
*/
|
|
92
|
+
reused?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* @description Test mode flag - true if created with test keys (sk_test_*)
|
|
95
|
+
* @example false
|
|
96
|
+
*/
|
|
97
|
+
testMode?: boolean;
|
|
98
|
+
};
|
|
99
|
+
UploadDocumentImageDto: {
|
|
100
|
+
/**
|
|
101
|
+
* @description KYC Session ID
|
|
102
|
+
* @example cm5abc123def456
|
|
103
|
+
*/
|
|
104
|
+
sessionId: string;
|
|
105
|
+
/**
|
|
106
|
+
* @description Image side/type
|
|
107
|
+
* @example front
|
|
108
|
+
* @enum {string}
|
|
109
|
+
*/
|
|
110
|
+
imageType: "front" | "back" | "main";
|
|
111
|
+
/**
|
|
112
|
+
* @description Whether this is a retake photo (replaces existing photo)
|
|
113
|
+
* @default false
|
|
114
|
+
* @example false
|
|
115
|
+
*/
|
|
116
|
+
isRetake: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Format: binary
|
|
119
|
+
* @description Single document image
|
|
120
|
+
*/
|
|
121
|
+
images: string;
|
|
122
|
+
};
|
|
123
|
+
DocumentUploadResponseDto: {
|
|
124
|
+
/** @example true */
|
|
125
|
+
success: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* @description Processing status: queued, processing, completed
|
|
128
|
+
* @example queued
|
|
129
|
+
*/
|
|
130
|
+
status: string;
|
|
131
|
+
/**
|
|
132
|
+
* @description Job ID for tracking
|
|
133
|
+
* @example doc:session123:front:1234567890
|
|
134
|
+
*/
|
|
135
|
+
jobId?: string;
|
|
136
|
+
/** @example passport */
|
|
137
|
+
detectedDocumentType: string;
|
|
138
|
+
/** @example 0.9 */
|
|
139
|
+
detectionConfidence: number;
|
|
140
|
+
/** @example front */
|
|
141
|
+
uploadedImageType: string;
|
|
142
|
+
/** @example front */
|
|
143
|
+
detectedSide?: string;
|
|
144
|
+
/** @example German ID Card */
|
|
145
|
+
documentName?: string;
|
|
146
|
+
/** @example true */
|
|
147
|
+
isValidDocument: boolean;
|
|
148
|
+
/** @example false */
|
|
149
|
+
requiresBackSide: boolean;
|
|
150
|
+
/** @example Please upload the back side of your ID card */
|
|
151
|
+
nextStepMessage: string;
|
|
152
|
+
/**
|
|
153
|
+
* @example {
|
|
154
|
+
* "front": true,
|
|
155
|
+
* "back": false
|
|
156
|
+
* }
|
|
157
|
+
*/
|
|
158
|
+
uploadedSides: Record<string, never>;
|
|
159
|
+
/** @example false */
|
|
160
|
+
readyForVerification: boolean;
|
|
161
|
+
/** @example Image uploaded successfully. Processing in background. */
|
|
162
|
+
message?: string;
|
|
163
|
+
/**
|
|
164
|
+
* @description Estimated processing time in milliseconds
|
|
165
|
+
* @example 3000
|
|
166
|
+
*/
|
|
167
|
+
estimatedProcessingTime?: number;
|
|
168
|
+
};
|
|
169
|
+
UploadFaceImageDto: {
|
|
170
|
+
/**
|
|
171
|
+
* @description KYC Session ID
|
|
172
|
+
* @example cm5abc123def456
|
|
173
|
+
*/
|
|
174
|
+
sessionId: string;
|
|
175
|
+
/**
|
|
176
|
+
* Format: binary
|
|
177
|
+
* @description Face image for biometric verification
|
|
178
|
+
*/
|
|
179
|
+
images: string;
|
|
180
|
+
};
|
|
181
|
+
FaceUploadResponseDto: {
|
|
182
|
+
/** @example true */
|
|
183
|
+
success: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* @description Processing status: queued, processing, completed
|
|
186
|
+
* @example queued
|
|
187
|
+
*/
|
|
188
|
+
status: string;
|
|
189
|
+
/**
|
|
190
|
+
* @description Job ID for tracking
|
|
191
|
+
* @example face:session123:1234567890
|
|
192
|
+
*/
|
|
193
|
+
jobId?: string;
|
|
194
|
+
/** @example 0.85 */
|
|
195
|
+
confidence: number;
|
|
196
|
+
/** @example Face image uploaded. Processing liveness in background. */
|
|
197
|
+
message: string;
|
|
198
|
+
/** @example true */
|
|
199
|
+
readyForFinalVerification: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* @description Estimated processing time in milliseconds
|
|
202
|
+
* @example 2000
|
|
203
|
+
*/
|
|
204
|
+
estimatedProcessingTime?: number;
|
|
205
|
+
};
|
|
206
|
+
UploadPoaImageDto: {
|
|
207
|
+
/**
|
|
208
|
+
* @description KYC Session ID
|
|
209
|
+
* @example cm5abc123def456
|
|
210
|
+
*/
|
|
211
|
+
sessionId: string;
|
|
212
|
+
/**
|
|
213
|
+
* Format: binary
|
|
214
|
+
* @description Proof of Address document (utility bill, bank statement, etc.). Supports JPEG, PNG, WebP, and PDF.
|
|
215
|
+
*/
|
|
216
|
+
images: string;
|
|
217
|
+
/** @description Custom extraction prompt (overrides default) */
|
|
218
|
+
prompt?: string;
|
|
219
|
+
};
|
|
220
|
+
PoaExtractedDataDto: {
|
|
221
|
+
/** @example John Doe */
|
|
222
|
+
fullName?: string;
|
|
223
|
+
/** @example 123 Main Street */
|
|
224
|
+
address?: string;
|
|
225
|
+
/** @example Berlin */
|
|
226
|
+
city?: string;
|
|
227
|
+
/** @example 10115 */
|
|
228
|
+
postalCode?: string;
|
|
229
|
+
/** @example Germany */
|
|
230
|
+
country?: string;
|
|
231
|
+
/** @example utility_bill */
|
|
232
|
+
documentType?: string;
|
|
233
|
+
/** @example 2025-01-15 */
|
|
234
|
+
issueDate?: string;
|
|
235
|
+
/** @example Berlin Electricity GmbH */
|
|
236
|
+
issuer?: string;
|
|
237
|
+
};
|
|
238
|
+
PoaConfidenceBreakdownDto: {
|
|
239
|
+
/**
|
|
240
|
+
* @example {
|
|
241
|
+
* "full_name": 1,
|
|
242
|
+
* "address": 1,
|
|
243
|
+
* "city": 0
|
|
244
|
+
* }
|
|
245
|
+
*/
|
|
246
|
+
fieldScores: Record<string, never>;
|
|
247
|
+
/** @example 1 */
|
|
248
|
+
totalWeight: number;
|
|
249
|
+
/** @example 0.75 */
|
|
250
|
+
achievedWeight: number;
|
|
251
|
+
/** @example 0.75 */
|
|
252
|
+
confidenceScore: number;
|
|
253
|
+
};
|
|
254
|
+
PoaUploadResponseDto: {
|
|
255
|
+
/** @example true */
|
|
256
|
+
success: boolean;
|
|
257
|
+
/** @example Proof of address uploaded and processed successfully */
|
|
258
|
+
message: string;
|
|
259
|
+
data?: components["schemas"]["PoaExtractedDataDto"];
|
|
260
|
+
/**
|
|
261
|
+
* @description Processing time in milliseconds
|
|
262
|
+
* @example 5000
|
|
263
|
+
*/
|
|
264
|
+
processingTimeMs?: number;
|
|
265
|
+
/**
|
|
266
|
+
* @description Whether session is ready for final verification
|
|
267
|
+
* @example true
|
|
268
|
+
*/
|
|
269
|
+
readyForVerification: boolean;
|
|
270
|
+
/**
|
|
271
|
+
* @description Confidence score from 0.0 to 1.0
|
|
272
|
+
* @example 0.85
|
|
273
|
+
*/
|
|
274
|
+
confidenceScore?: number;
|
|
275
|
+
confidenceBreakdown?: components["schemas"]["PoaConfidenceBreakdownDto"];
|
|
276
|
+
/**
|
|
277
|
+
* @description PoA verification status based on confidence thresholds
|
|
278
|
+
* @example auto_approved
|
|
279
|
+
* @enum {string}
|
|
280
|
+
*/
|
|
281
|
+
poaStatus?: "pending" | "auto_approved" | "manual_review" | "approved" | "rejected";
|
|
282
|
+
};
|
|
283
|
+
PoaAsyncResponseDto: {
|
|
284
|
+
/** @example true */
|
|
285
|
+
success: boolean;
|
|
286
|
+
/** @example f47ac10b-58cc-4372-a567-0e02b2c3d479 */
|
|
287
|
+
jobId: string;
|
|
288
|
+
/**
|
|
289
|
+
* @example processing
|
|
290
|
+
* @enum {string}
|
|
291
|
+
*/
|
|
292
|
+
status: "processing";
|
|
293
|
+
/** @example PoA extraction started. Poll /kyc/poa-status/:jobId for results. */
|
|
294
|
+
message: string;
|
|
295
|
+
};
|
|
296
|
+
PoaStatusResponseDto: {
|
|
297
|
+
/** @example f47ac10b-58cc-4372-a567-0e02b2c3d479 */
|
|
298
|
+
jobId: string;
|
|
299
|
+
/**
|
|
300
|
+
* @example completed
|
|
301
|
+
* @enum {string}
|
|
302
|
+
*/
|
|
303
|
+
status: "processing" | "completed" | "failed" | "not_found";
|
|
304
|
+
/** @example PoA extraction completed */
|
|
305
|
+
message: string;
|
|
306
|
+
data?: components["schemas"]["PoaExtractedDataDto"];
|
|
307
|
+
/**
|
|
308
|
+
* @description Confidence score from 0.0 to 1.0
|
|
309
|
+
* @example 0.85
|
|
310
|
+
*/
|
|
311
|
+
confidenceScore?: number;
|
|
312
|
+
/**
|
|
313
|
+
* @example auto_approved
|
|
314
|
+
* @enum {string}
|
|
315
|
+
*/
|
|
316
|
+
poaStatus?: "pending" | "auto_approved" | "manual_review" | "approved" | "rejected";
|
|
317
|
+
};
|
|
318
|
+
ExtractedDataDto: {
|
|
319
|
+
/** @example John Doe */
|
|
320
|
+
fullName: string;
|
|
321
|
+
/** @example John */
|
|
322
|
+
firstName: string;
|
|
323
|
+
/** @example Doe */
|
|
324
|
+
lastName: string;
|
|
325
|
+
/** @example 1990-01-01 */
|
|
326
|
+
dateOfBirth: string;
|
|
327
|
+
/** @example German */
|
|
328
|
+
nationality: string;
|
|
329
|
+
/** @example M */
|
|
330
|
+
sex: string;
|
|
331
|
+
};
|
|
332
|
+
VerificationDataDto: {
|
|
333
|
+
/** @example id_card */
|
|
334
|
+
documentType: string;
|
|
335
|
+
extractedData: components["schemas"]["ExtractedDataDto"];
|
|
336
|
+
/** @example atm_1a2b3c4d5e */
|
|
337
|
+
verificationAttemptId: string;
|
|
338
|
+
};
|
|
339
|
+
VerificationResponseDto: {
|
|
340
|
+
/** @example true */
|
|
341
|
+
success: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* @description Processing status: queued, processing, completed, failed
|
|
344
|
+
* @example queued
|
|
345
|
+
*/
|
|
346
|
+
status?: string;
|
|
347
|
+
/**
|
|
348
|
+
* @description Job ID for tracking
|
|
349
|
+
* @example verify:session123:1234567890
|
|
350
|
+
*/
|
|
351
|
+
jobId?: string;
|
|
352
|
+
/** @example Verification started. You will receive results shortly. */
|
|
353
|
+
message?: string;
|
|
354
|
+
/** @example client123 */
|
|
355
|
+
clientId?: string;
|
|
356
|
+
/** @example 2024-01-15T10:30:00Z */
|
|
357
|
+
timestamp?: string;
|
|
358
|
+
/** @example 0.95 */
|
|
359
|
+
confidence?: number;
|
|
360
|
+
data?: components["schemas"]["VerificationDataDto"];
|
|
361
|
+
/**
|
|
362
|
+
* @description PoA verification status: auto_approved, manual_review, rejected, pending
|
|
363
|
+
* @example auto_approved
|
|
364
|
+
*/
|
|
365
|
+
poaStatus?: string;
|
|
366
|
+
};
|
|
367
|
+
GrantVaultConsentDto: {
|
|
368
|
+
/** @description KYC session id whose primary verification just completed. */
|
|
369
|
+
sessionId: string;
|
|
370
|
+
/** @description Version of consent text the user agreed to. */
|
|
371
|
+
consentVersion?: string;
|
|
372
|
+
};
|
|
373
|
+
GrantVaultConsentResponseDto: {
|
|
374
|
+
verifiedIdentityId: string;
|
|
375
|
+
vaultPrefix: string;
|
|
376
|
+
consentVersion: string;
|
|
377
|
+
/** Format: date-time */
|
|
378
|
+
consentAt: string;
|
|
379
|
+
};
|
|
380
|
+
CheckVaultDto: {
|
|
381
|
+
/** @description KYC session id (current new session). */
|
|
382
|
+
sessionId: string;
|
|
383
|
+
};
|
|
384
|
+
CheckVaultResponseDto: {
|
|
385
|
+
available: boolean;
|
|
386
|
+
/** @enum {string} */
|
|
387
|
+
mode?: "full_reuse" | "partial_reuse_poa";
|
|
388
|
+
/** Format: date-time */
|
|
389
|
+
completedAt?: string;
|
|
390
|
+
sourceProjectName?: string;
|
|
391
|
+
documentType?: Record<string, never>;
|
|
392
|
+
vaultHasPoa?: boolean;
|
|
393
|
+
projectRequiresPoa?: boolean;
|
|
394
|
+
/**
|
|
395
|
+
* @description Identity proof method the widget must show before applying reuse.
|
|
396
|
+
* @enum {string}
|
|
397
|
+
*/
|
|
398
|
+
challengeMethod?: "otp" | "liveness";
|
|
399
|
+
};
|
|
400
|
+
RequestVaultOtpDto: {
|
|
401
|
+
/** @description Current widget session id. */
|
|
402
|
+
sessionId: string;
|
|
403
|
+
};
|
|
404
|
+
RequestVaultOtpResponseDto: {
|
|
405
|
+
/** @description Always true — the endpoint does not reveal whether the email actually matches a vault entry. */
|
|
406
|
+
sent: boolean;
|
|
407
|
+
};
|
|
408
|
+
VerifyVaultOtpDto: {
|
|
409
|
+
sessionId: string;
|
|
410
|
+
/** @description 6-digit numeric code received by email. */
|
|
411
|
+
code: string;
|
|
412
|
+
};
|
|
413
|
+
VerifyVaultOtpResponseDto: {
|
|
414
|
+
verified: boolean;
|
|
415
|
+
};
|
|
416
|
+
VaultIdentityChallengeDto: {
|
|
417
|
+
sessionId: string;
|
|
418
|
+
/** @description Burst of selfie frames (Beta auto-capture). 1-6 frames. */
|
|
419
|
+
selfiesBase64?: string[];
|
|
420
|
+
/** @description Legacy single-selfie path. Prefer `selfiesBase64` for Beta burst. May include a "data:image/jpeg;base64," prefix or be raw base64. */
|
|
421
|
+
selfieBase64?: string;
|
|
422
|
+
};
|
|
423
|
+
VaultIdentityChallengeResponseDto: {
|
|
424
|
+
verified: boolean;
|
|
425
|
+
/** @description Face-match similarity score (0..1) when computed. */
|
|
426
|
+
similarity?: number;
|
|
427
|
+
liveness?: Record<string, never>;
|
|
428
|
+
/** @enum {string} */
|
|
429
|
+
reason?: "no_email" | "no_vault" | "no_portrait" | "liveness_failed" | "face_mismatch";
|
|
430
|
+
};
|
|
431
|
+
ApplyVaultReuseDto: {
|
|
432
|
+
sessionId: string;
|
|
433
|
+
/** @enum {string} */
|
|
434
|
+
mode: "full_reuse" | "partial_reuse_poa";
|
|
435
|
+
};
|
|
436
|
+
ApplyVaultReuseResponseDto: {
|
|
437
|
+
attemptId: string;
|
|
438
|
+
verifiedIdentityId: string;
|
|
439
|
+
/** @enum {string} */
|
|
440
|
+
mode: "full_reuse" | "partial_reuse_poa";
|
|
441
|
+
};
|
|
442
|
+
RevokeIdentityDto: {
|
|
443
|
+
/** @description Email whose vault entry should be revoked. Must match a session-verified email. */
|
|
444
|
+
email: string;
|
|
445
|
+
/** @description Optional human-readable reason. */
|
|
446
|
+
reason?: string;
|
|
447
|
+
};
|
|
448
|
+
RevokeIdentityResponseDto: {
|
|
449
|
+
revoked: boolean;
|
|
450
|
+
/** Format: date-time */
|
|
451
|
+
revokedAt: string;
|
|
452
|
+
};
|
|
453
|
+
MarkAllReadDto: Record<string, never>;
|
|
454
|
+
SendOtpDto: Record<string, never>;
|
|
455
|
+
VerifyOtpDto: Record<string, never>;
|
|
456
|
+
ResendOtpDto: Record<string, never>;
|
|
457
|
+
CreateBillingProfileDto: {
|
|
458
|
+
/** @description Company name (required for B2B invoicing) */
|
|
459
|
+
companyName?: string;
|
|
460
|
+
/** @description VAT/Tax ID number (EU format: XX followed by numbers) */
|
|
461
|
+
vatNumber?: string;
|
|
462
|
+
/** @description Alternative tax identification */
|
|
463
|
+
taxId?: string;
|
|
464
|
+
/** @description Address line 1 */
|
|
465
|
+
addressLine1?: string;
|
|
466
|
+
/** @description Address line 2 */
|
|
467
|
+
addressLine2?: string;
|
|
468
|
+
/** @description City */
|
|
469
|
+
city?: string;
|
|
470
|
+
/** @description State/Province */
|
|
471
|
+
state?: string;
|
|
472
|
+
/** @description Postal/ZIP code */
|
|
473
|
+
postalCode?: string;
|
|
474
|
+
/** @description Country code (2-letter ISO) */
|
|
475
|
+
country?: string;
|
|
476
|
+
/** @description Contact person name */
|
|
477
|
+
contactName?: string;
|
|
478
|
+
/** @description Email for receiving invoices */
|
|
479
|
+
contactEmail?: string;
|
|
480
|
+
/** @description Contact phone number */
|
|
481
|
+
contactPhone?: string;
|
|
482
|
+
/** @description Customer reference number for invoices */
|
|
483
|
+
invoiceRecipientNumber?: string;
|
|
484
|
+
/** @description Custom notes to include on invoices */
|
|
485
|
+
invoiceNotes?: string;
|
|
486
|
+
/**
|
|
487
|
+
* @description Preferred currency (EUR, USD, etc.)
|
|
488
|
+
* @default EUR
|
|
489
|
+
*/
|
|
490
|
+
preferredCurrency: string;
|
|
491
|
+
/**
|
|
492
|
+
* @description Auto-generate monthly invoices
|
|
493
|
+
* @default true
|
|
494
|
+
*/
|
|
495
|
+
autoInvoice: boolean;
|
|
496
|
+
};
|
|
497
|
+
UpdateBillingProfileDto: {
|
|
498
|
+
/** @description Company name (required for B2B invoicing) */
|
|
499
|
+
companyName?: string;
|
|
500
|
+
/** @description VAT/Tax ID number (EU format: XX followed by numbers) */
|
|
501
|
+
vatNumber?: string;
|
|
502
|
+
/** @description Alternative tax identification */
|
|
503
|
+
taxId?: string;
|
|
504
|
+
/** @description Address line 1 */
|
|
505
|
+
addressLine1?: string;
|
|
506
|
+
/** @description Address line 2 */
|
|
507
|
+
addressLine2?: string;
|
|
508
|
+
/** @description City */
|
|
509
|
+
city?: string;
|
|
510
|
+
/** @description State/Province */
|
|
511
|
+
state?: string;
|
|
512
|
+
/** @description Postal/ZIP code */
|
|
513
|
+
postalCode?: string;
|
|
514
|
+
/** @description Country code (2-letter ISO) */
|
|
515
|
+
country?: string;
|
|
516
|
+
/** @description Contact person name */
|
|
517
|
+
contactName?: string;
|
|
518
|
+
/** @description Email for receiving invoices */
|
|
519
|
+
contactEmail?: string;
|
|
520
|
+
/** @description Contact phone number */
|
|
521
|
+
contactPhone?: string;
|
|
522
|
+
/** @description Customer reference number for invoices */
|
|
523
|
+
invoiceRecipientNumber?: string;
|
|
524
|
+
/** @description Custom notes to include on invoices */
|
|
525
|
+
invoiceNotes?: string;
|
|
526
|
+
/**
|
|
527
|
+
* @description Preferred currency (EUR, USD, etc.)
|
|
528
|
+
* @default EUR
|
|
529
|
+
*/
|
|
530
|
+
preferredCurrency: string;
|
|
531
|
+
/**
|
|
532
|
+
* @description Auto-generate monthly invoices
|
|
533
|
+
* @default true
|
|
534
|
+
*/
|
|
535
|
+
autoInvoice: boolean;
|
|
536
|
+
};
|
|
537
|
+
ValidateVatDto: {
|
|
538
|
+
/** @description VAT number to validate (EU format) */
|
|
539
|
+
vatNumber: string;
|
|
540
|
+
};
|
|
541
|
+
TopUpBalanceDto: {
|
|
542
|
+
/**
|
|
543
|
+
* @description Amount to add to balance
|
|
544
|
+
* @example 50
|
|
545
|
+
*/
|
|
546
|
+
amount: number;
|
|
547
|
+
/** @description Payment method reference (e.g., Stripe payment intent ID) */
|
|
548
|
+
paymentReference?: string;
|
|
549
|
+
/** @description Type of payment reference (e.g., stripe_payment, manual_topup) */
|
|
550
|
+
referenceType?: string;
|
|
551
|
+
/** @description Description for the top-up */
|
|
552
|
+
description?: string;
|
|
553
|
+
};
|
|
554
|
+
BalanceSettingsDto: {
|
|
555
|
+
/** @description Low balance alert threshold */
|
|
556
|
+
lowBalanceThreshold?: number;
|
|
557
|
+
/** @description Enable automatic top-up */
|
|
558
|
+
autoTopUpEnabled?: boolean;
|
|
559
|
+
/** @description Amount to auto top-up when balance is low */
|
|
560
|
+
autoTopUpAmount?: number;
|
|
561
|
+
/** @description Balance threshold to trigger auto top-up */
|
|
562
|
+
autoTopUpThreshold?: number;
|
|
563
|
+
/** @description Credit limit for negative balance */
|
|
564
|
+
creditLimit?: number;
|
|
565
|
+
};
|
|
566
|
+
PaylinqWebhookResponse: {
|
|
567
|
+
success: boolean;
|
|
568
|
+
message: string;
|
|
569
|
+
};
|
|
570
|
+
AddPaymentMethodDto: Record<string, never>;
|
|
571
|
+
CreateProjectDto: Record<string, never>;
|
|
572
|
+
UpdateProjectDto: Record<string, never>;
|
|
573
|
+
UpdatePoaSettingsDto: {
|
|
574
|
+
/**
|
|
575
|
+
* @description Enable PoA verification for this environment
|
|
576
|
+
* @example true
|
|
577
|
+
*/
|
|
578
|
+
poaEnabled?: boolean;
|
|
579
|
+
/**
|
|
580
|
+
* @description Threshold for auto-approval (0.0-1.0). Documents above this confidence are auto-approved.
|
|
581
|
+
* @example 0.7
|
|
582
|
+
*/
|
|
583
|
+
poaAutoApproveThreshold?: number;
|
|
584
|
+
/**
|
|
585
|
+
* @description Threshold for manual review (0.0-1.0). Documents between this and auto-approve threshold require manual review.
|
|
586
|
+
* @example 0.5
|
|
587
|
+
*/
|
|
588
|
+
poaManualReviewThreshold?: number;
|
|
589
|
+
/**
|
|
590
|
+
* @description Block final verification until PoA is approved
|
|
591
|
+
* @example false
|
|
592
|
+
*/
|
|
593
|
+
poaRequiredForVerification?: boolean;
|
|
594
|
+
/**
|
|
595
|
+
* @description Force all PoA to go through manual review (disable auto-approve)
|
|
596
|
+
* @example false
|
|
597
|
+
*/
|
|
598
|
+
poaForceManualReview?: boolean;
|
|
599
|
+
};
|
|
600
|
+
RetryWebhookDeliveryDto: Record<string, never>;
|
|
601
|
+
InviteTeamMemberDto: Record<string, never>;
|
|
602
|
+
UpdateMemberRoleDto: Record<string, never>;
|
|
603
|
+
AcceptInvitationDto: Record<string, never>;
|
|
604
|
+
RegisterDto: Record<string, never>;
|
|
605
|
+
UpdateProfileDto: Record<string, never>;
|
|
606
|
+
ChangePasswordDto: Record<string, never>;
|
|
607
|
+
SetPasswordDto: Record<string, never>;
|
|
608
|
+
ResetPasswordDto: Record<string, never>;
|
|
609
|
+
CreateContactRequestDto: {
|
|
610
|
+
/**
|
|
611
|
+
* @description Full name of the person making contact
|
|
612
|
+
* @example John Doe
|
|
613
|
+
*/
|
|
614
|
+
name: string;
|
|
615
|
+
/**
|
|
616
|
+
* @description Email address for contact
|
|
617
|
+
* @example john.doe@example.com
|
|
618
|
+
*/
|
|
619
|
+
email: string;
|
|
620
|
+
};
|
|
621
|
+
ContactRequestResponseDto: {
|
|
622
|
+
/** @description Unique identifier for the contact request */
|
|
623
|
+
id: string;
|
|
624
|
+
/** @description Contact person name */
|
|
625
|
+
name: string;
|
|
626
|
+
/** @description Contact email address */
|
|
627
|
+
email: string;
|
|
628
|
+
/**
|
|
629
|
+
* @description Source of the contact request
|
|
630
|
+
* @example landing
|
|
631
|
+
*/
|
|
632
|
+
source: string;
|
|
633
|
+
/**
|
|
634
|
+
* @description Status of the contact request
|
|
635
|
+
* @example new
|
|
636
|
+
*/
|
|
637
|
+
status: string;
|
|
638
|
+
/**
|
|
639
|
+
* Format: date-time
|
|
640
|
+
* @description Timestamp when the request was created
|
|
641
|
+
*/
|
|
642
|
+
createdAt: string;
|
|
643
|
+
};
|
|
644
|
+
CreateSessionDto: {
|
|
645
|
+
/**
|
|
646
|
+
* @description Custom client metadata for identification and tracking
|
|
647
|
+
* @example {
|
|
648
|
+
* "userId": "user_12345",
|
|
649
|
+
* "email": "john.doe@example.com",
|
|
650
|
+
* "name": "John Doe",
|
|
651
|
+
* "accountType": "premium"
|
|
652
|
+
* }
|
|
653
|
+
*/
|
|
654
|
+
clientMetadata?: Record<string, never>;
|
|
655
|
+
/**
|
|
656
|
+
* @description Session expiry time in minutes (default: 5, max: 60)
|
|
657
|
+
* @example 30
|
|
658
|
+
*/
|
|
659
|
+
expiryMinutes?: number;
|
|
660
|
+
/**
|
|
661
|
+
* @description Language for widget UI
|
|
662
|
+
* @example de
|
|
663
|
+
* @enum {string}
|
|
664
|
+
*/
|
|
665
|
+
language?: "en" | "de" | "uk";
|
|
666
|
+
/**
|
|
667
|
+
* @description Server-side metadata for internal tracking
|
|
668
|
+
* @example {
|
|
669
|
+
* "requestId": "req_123",
|
|
670
|
+
* "sourceIp": "192.168.1.1",
|
|
671
|
+
* "userAgent": "MyApp/1.0"
|
|
672
|
+
* }
|
|
673
|
+
*/
|
|
674
|
+
serverMetadata?: Record<string, never>;
|
|
675
|
+
};
|
|
676
|
+
SessionDetailsDto: {
|
|
677
|
+
/**
|
|
678
|
+
* @description Unique session identifier
|
|
679
|
+
* @example clx1234567890abcdef
|
|
680
|
+
*/
|
|
681
|
+
id: string;
|
|
682
|
+
/**
|
|
683
|
+
* @description Session status
|
|
684
|
+
* @example pending
|
|
685
|
+
* @enum {string}
|
|
686
|
+
*/
|
|
687
|
+
status: "pending" | "in_progress" | "completed" | "failed" | "expired";
|
|
688
|
+
/**
|
|
689
|
+
* Format: date-time
|
|
690
|
+
* @description Session expiration timestamp
|
|
691
|
+
* @example 2024-10-25T14:30:00.000Z
|
|
692
|
+
*/
|
|
693
|
+
expiresAt: string;
|
|
694
|
+
/**
|
|
695
|
+
* @description Client metadata
|
|
696
|
+
* @example {
|
|
697
|
+
* "userId": "user_12345",
|
|
698
|
+
* "email": "john.doe@example.com"
|
|
699
|
+
* }
|
|
700
|
+
*/
|
|
701
|
+
clientMetadata?: Record<string, never>;
|
|
702
|
+
/**
|
|
703
|
+
* @description Widget URL for embedding
|
|
704
|
+
* @example https://widget.flonk.id/?sessionId=clx1234567890abcdef&mode=embedded
|
|
705
|
+
*/
|
|
706
|
+
widgetUrl: string;
|
|
707
|
+
/**
|
|
708
|
+
* @description QR code data for mobile verification
|
|
709
|
+
* @example https://widget.flonk.id/verify/clx1234567890abcdef?token=kyc_1234567890_abc123
|
|
710
|
+
*/
|
|
711
|
+
qrCodeUrl: string;
|
|
712
|
+
/**
|
|
713
|
+
* Format: date-time
|
|
714
|
+
* @description Session creation timestamp
|
|
715
|
+
* @example 2024-10-25T14:25:00.000Z
|
|
716
|
+
*/
|
|
717
|
+
createdAt: string;
|
|
718
|
+
/**
|
|
719
|
+
* @description Project identifier
|
|
720
|
+
* @example clxproject123
|
|
721
|
+
*/
|
|
722
|
+
projectId: string;
|
|
723
|
+
/**
|
|
724
|
+
* @description Whether manual upload is allowed for this session
|
|
725
|
+
* @example true
|
|
726
|
+
*/
|
|
727
|
+
allowManualUpload: boolean;
|
|
728
|
+
/**
|
|
729
|
+
* @description Embed token for widget authentication (like Stripe client_secret)
|
|
730
|
+
* @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
731
|
+
*/
|
|
732
|
+
embedToken?: string;
|
|
733
|
+
/**
|
|
734
|
+
* @description Indicates if an existing session was reused instead of creating a new one
|
|
735
|
+
* @example false
|
|
736
|
+
*/
|
|
737
|
+
reused?: boolean;
|
|
738
|
+
/**
|
|
739
|
+
* @description Test mode flag - true if created with test keys (sk_test_*)
|
|
740
|
+
* @example false
|
|
741
|
+
*/
|
|
742
|
+
testMode?: boolean;
|
|
743
|
+
/**
|
|
744
|
+
* Format: date-time
|
|
745
|
+
* @description Last activity timestamp
|
|
746
|
+
* @example 2024-10-25T14:28:00.000Z
|
|
747
|
+
*/
|
|
748
|
+
lastActivity?: string;
|
|
749
|
+
/**
|
|
750
|
+
* @description Server metadata
|
|
751
|
+
* @example {
|
|
752
|
+
* "requestId": "req_123",
|
|
753
|
+
* "sourceIp": "192.168.1.1"
|
|
754
|
+
* }
|
|
755
|
+
*/
|
|
756
|
+
serverMetadata?: Record<string, never>;
|
|
757
|
+
/**
|
|
758
|
+
* Format: date-time
|
|
759
|
+
* @description Last update timestamp
|
|
760
|
+
* @example 2024-10-25T14:28:00.000Z
|
|
761
|
+
*/
|
|
762
|
+
updatedAt: string;
|
|
763
|
+
};
|
|
764
|
+
UpdateStatusDto: Record<string, never>;
|
|
765
|
+
AddNoteDto: Record<string, never>;
|
|
766
|
+
UploadDocumentDto: {
|
|
767
|
+
/** @enum {string} */
|
|
768
|
+
documentType: "main" | "back" | "face" | "passport" | "id_card" | "driver_license" | "utility_bill" | "bank_statement" | "selfie";
|
|
769
|
+
};
|
|
770
|
+
UpdateSystemRoleDto: Record<string, never>;
|
|
771
|
+
SuspendUserDto: Record<string, never>;
|
|
772
|
+
UnsuspendUserDto: Record<string, never>;
|
|
773
|
+
ChangeMembershipRoleDto: Record<string, never>;
|
|
774
|
+
AddMembershipDto: Record<string, never>;
|
|
775
|
+
SuspendProjectDto: Record<string, never>;
|
|
776
|
+
UnsuspendProjectDto: Record<string, never>;
|
|
777
|
+
UpdateBrandingDto: Record<string, never>;
|
|
778
|
+
UpdateWebhookDto: Record<string, never>;
|
|
779
|
+
UpdateFaceAutoCaptureDto: Record<string, never>;
|
|
780
|
+
AddDomainDto: Record<string, never>;
|
|
781
|
+
CreditBalanceDto: Record<string, never>;
|
|
782
|
+
DebitBalanceDto: Record<string, never>;
|
|
783
|
+
ApproveProjectDto: Record<string, never>;
|
|
784
|
+
RejectProjectDto: Record<string, never>;
|
|
785
|
+
CreateInviteDto: Record<string, never>;
|
|
786
|
+
AcceptInviteDto: Record<string, never>;
|
|
787
|
+
UpdatePlatformFaceAutoCaptureDto: Record<string, never>;
|
|
788
|
+
WebhookExtractedDataDto: {
|
|
789
|
+
full_name?: string | null;
|
|
790
|
+
first_name?: string | null;
|
|
791
|
+
last_name?: string | null;
|
|
792
|
+
date_of_birth?: string | null;
|
|
793
|
+
nationality?: string | null;
|
|
794
|
+
sex?: string | null;
|
|
795
|
+
issue_date?: string | null;
|
|
796
|
+
expiry_date?: string | null;
|
|
797
|
+
place_of_birth?: string | null;
|
|
798
|
+
};
|
|
799
|
+
WebhookPoaVerificationDto: {
|
|
800
|
+
status: string;
|
|
801
|
+
confidence_score: number | null;
|
|
802
|
+
verified_address?: string | null;
|
|
803
|
+
address_match?: boolean;
|
|
804
|
+
};
|
|
805
|
+
WebhookDuplicateVerificationDto: {
|
|
806
|
+
is_duplicate: boolean;
|
|
807
|
+
previous_verification_id: string;
|
|
808
|
+
previous_verified_at: string;
|
|
809
|
+
/** @enum {string} */
|
|
810
|
+
match_type: "document_number" | "personal_data";
|
|
811
|
+
similarity_score: number;
|
|
812
|
+
};
|
|
813
|
+
WebhookReuseSourceDto: {
|
|
814
|
+
/** @enum {number} */
|
|
815
|
+
is_reused: true;
|
|
816
|
+
verified_identity_id: string;
|
|
817
|
+
original_project_id: string | null;
|
|
818
|
+
original_attempt_id: string;
|
|
819
|
+
original_completed_at: string;
|
|
820
|
+
consent_at: string;
|
|
821
|
+
mode: string;
|
|
822
|
+
};
|
|
823
|
+
WebhookEventObjectDto: {
|
|
824
|
+
id: string;
|
|
825
|
+
client_id?: string;
|
|
826
|
+
client_metadata?: {
|
|
827
|
+
[key: string]: unknown;
|
|
828
|
+
};
|
|
829
|
+
status: string;
|
|
830
|
+
confidence?: number;
|
|
831
|
+
document_type: string;
|
|
832
|
+
extracted_data: components["schemas"]["WebhookExtractedDataDto"];
|
|
833
|
+
created_at: string;
|
|
834
|
+
updated_at?: string;
|
|
835
|
+
updated_by?: string;
|
|
836
|
+
test_mode?: boolean;
|
|
837
|
+
poa_verification?: components["schemas"]["WebhookPoaVerificationDto"];
|
|
838
|
+
duplicate_verification?: components["schemas"]["WebhookDuplicateVerificationDto"];
|
|
839
|
+
reuse_source?: components["schemas"]["WebhookReuseSourceDto"];
|
|
840
|
+
previous_status?: string;
|
|
841
|
+
rejection_reason?: string;
|
|
842
|
+
reviewed_by?: string;
|
|
843
|
+
};
|
|
844
|
+
WebhookEventDataDto: {
|
|
845
|
+
object: components["schemas"]["WebhookEventObjectDto"];
|
|
846
|
+
};
|
|
847
|
+
WebhookEventDto: {
|
|
848
|
+
id: string;
|
|
849
|
+
/** @enum {string} */
|
|
850
|
+
type: "verification.completed" | "verification.status_changed" | "verification.updated";
|
|
851
|
+
created: number;
|
|
852
|
+
livemode: boolean;
|
|
853
|
+
data: components["schemas"]["WebhookEventDataDto"];
|
|
854
|
+
};
|
|
855
|
+
};
|
|
856
|
+
responses: never;
|
|
857
|
+
parameters: never;
|
|
858
|
+
requestBodies: never;
|
|
859
|
+
headers: never;
|
|
860
|
+
pathItems: never;
|
|
861
|
+
}
|
|
862
|
+
|
|
1
863
|
type SessionStatus = 'pending' | 'connected' | 'processing' | 'completed' | 'failed' | 'expired';
|
|
2
864
|
type DocumentType = 'passport' | 'id_card' | 'driver_license';
|
|
3
865
|
type WidgetLanguage = 'en' | 'de' | 'uk';
|
|
@@ -5,6 +867,12 @@ interface FlonkKYCServerOptions {
|
|
|
5
867
|
secretKey: string;
|
|
6
868
|
apiBase?: string;
|
|
7
869
|
timeout?: number;
|
|
870
|
+
/** Max retry attempts for transient failures (429/5xx/network). Default 2. */
|
|
871
|
+
maxRetries?: number;
|
|
872
|
+
/** Base backoff in ms (full-jittered exponential). Default 250. */
|
|
873
|
+
retryBaseMs?: number;
|
|
874
|
+
/** Pin the REST API version (`Flonk-Version` header). Default: the SDK's build version. */
|
|
875
|
+
apiVersion?: string;
|
|
8
876
|
}
|
|
9
877
|
interface CreateSessionParams {
|
|
10
878
|
clientMetadata?: Record<string, unknown>;
|
|
@@ -12,6 +880,13 @@ interface CreateSessionParams {
|
|
|
12
880
|
expiryMinutes?: number;
|
|
13
881
|
language?: WidgetLanguage;
|
|
14
882
|
serverMetadata?: Record<string, unknown>;
|
|
883
|
+
/**
|
|
884
|
+
* Idempotency key for this create. A retry with the same key returns the
|
|
885
|
+
* original session instead of creating a new one. Auto-generated (UUID) per
|
|
886
|
+
* call if omitted; supply your own to make a specific create idempotent
|
|
887
|
+
* across process restarts.
|
|
888
|
+
*/
|
|
889
|
+
idempotencyKey?: string;
|
|
15
890
|
}
|
|
16
891
|
interface Session {
|
|
17
892
|
id: string;
|
|
@@ -36,42 +911,48 @@ interface UpdateSessionParams {
|
|
|
36
911
|
clientMetadata?: Record<string, unknown>;
|
|
37
912
|
serverMetadata?: Record<string, unknown>;
|
|
38
913
|
}
|
|
39
|
-
|
|
914
|
+
type WebhookSchemas = components['schemas'];
|
|
915
|
+
type WebhookObjectFull = WebhookSchemas['WebhookEventObjectDto'];
|
|
916
|
+
/** Fields common to every verification webhook's `data.object` (generated). */
|
|
917
|
+
type WebhookObjectBase = Omit<WebhookObjectFull, 'duplicate_verification' | 'reuse_source' | 'previous_status' | 'rejection_reason' | 'reviewed_by' | 'updated_at' | 'updated_by'>;
|
|
918
|
+
interface WebhookEventBase {
|
|
40
919
|
id: string;
|
|
41
|
-
type: 'verification.completed' | 'verification.status_changed' | 'verification.updated';
|
|
42
920
|
created: number;
|
|
43
921
|
livemode: boolean;
|
|
922
|
+
}
|
|
923
|
+
/** Automated AI verification finished. */
|
|
924
|
+
interface VerificationCompletedEvent extends WebhookEventBase {
|
|
925
|
+
type: 'verification.completed';
|
|
44
926
|
data: {
|
|
45
|
-
object:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
};
|
|
61
|
-
created_at: string;
|
|
62
|
-
updated_at?: string;
|
|
63
|
-
updated_by?: string;
|
|
64
|
-
test_mode?: boolean;
|
|
65
|
-
poa_verification?: {
|
|
66
|
-
status: string;
|
|
67
|
-
confidence_score: number | null;
|
|
68
|
-
};
|
|
69
|
-
previous_status?: string;
|
|
70
|
-
rejection_reason?: string;
|
|
71
|
-
reviewed_by?: string;
|
|
72
|
-
};
|
|
927
|
+
object: WebhookObjectBase & Pick<WebhookObjectFull, 'duplicate_verification' | 'reuse_source'>;
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
/** An admin manually approved/rejected the verification. */
|
|
931
|
+
interface VerificationStatusChangedEvent extends WebhookEventBase {
|
|
932
|
+
type: 'verification.status_changed';
|
|
933
|
+
data: {
|
|
934
|
+
object: WebhookObjectBase & Pick<WebhookObjectFull, 'previous_status' | 'rejection_reason' | 'reviewed_by'>;
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
/** An admin edited verification data, or async PoA review finished. */
|
|
938
|
+
interface VerificationUpdatedEvent extends WebhookEventBase {
|
|
939
|
+
type: 'verification.updated';
|
|
940
|
+
data: {
|
|
941
|
+
object: WebhookObjectBase & Pick<WebhookObjectFull, 'updated_at' | 'updated_by'>;
|
|
73
942
|
};
|
|
74
943
|
}
|
|
944
|
+
/**
|
|
945
|
+
* Closed discriminated union — the Stripe approach. `event.type` narrows
|
|
946
|
+
* `event.data.object`, so a `switch (event.type)` is type-safe and exhaustive,
|
|
947
|
+
* and per-event fields live only on the events that carry them. Kept current by
|
|
948
|
+
* the OpenAPI codegen pipeline (TYPES.md): a new platform event type is picked
|
|
949
|
+
* up on the next generation. A brand-new type still arrives at runtime
|
|
950
|
+
* (`constructEvent` never rejects it) — handle it in the `default` branch, and
|
|
951
|
+
* cast if you must reference it before regenerating.
|
|
952
|
+
*/
|
|
953
|
+
type WebhookEvent = VerificationCompletedEvent | VerificationStatusChangedEvent | VerificationUpdatedEvent;
|
|
954
|
+
/** Union of every event `type` literal this SDK knows. */
|
|
955
|
+
type WebhookEventType = WebhookEvent['type'];
|
|
75
956
|
interface WebhookVerifyOptions {
|
|
76
957
|
/** Max clock skew in seconds. Default: 300 */
|
|
77
958
|
maxSkewSeconds?: number;
|
|
@@ -79,7 +960,13 @@ interface WebhookVerifyOptions {
|
|
|
79
960
|
|
|
80
961
|
declare class Webhooks {
|
|
81
962
|
/**
|
|
82
|
-
* Verify X-Signature-256 header: "sha256=<hex>"
|
|
963
|
+
* Verify X-Signature-256 header: "sha256=<hex>".
|
|
964
|
+
*
|
|
965
|
+
* NOTE: this format carries no timestamp, so it has **no replay protection** —
|
|
966
|
+
* a captured request stays valid forever. Prefer {@link verifyTimestampSignature}
|
|
967
|
+
* (the `t=,v1=` header, sent as `X-Signature`), and dedupe by `event.id` in
|
|
968
|
+
* your own store (a unique index, or Redis `SET id 1 NX EX <ttl>`) so retries
|
|
969
|
+
* are processed once.
|
|
83
970
|
*/
|
|
84
971
|
verifySignature(payload: string, signature: string, secret: string): WebhookEvent;
|
|
85
972
|
/**
|
|
@@ -92,11 +979,18 @@ declare class Webhooks {
|
|
|
92
979
|
constructEvent(payload: string, signature: string, secret: string): WebhookEvent;
|
|
93
980
|
private parsePayload;
|
|
94
981
|
private parseHeader;
|
|
982
|
+
/**
|
|
983
|
+
* Constant-time string compare with no length-dependent branch: HMAC both
|
|
984
|
+
* sides with a per-call random key so the compared buffers are always 32
|
|
985
|
+
* bytes regardless of input length, then timingSafeEqual. Equal digests imply
|
|
986
|
+
* equal inputs (HMAC collision resistance), so this leaks neither the result
|
|
987
|
+
* nor the length via timing.
|
|
988
|
+
*/
|
|
95
989
|
private safeEqual;
|
|
96
990
|
}
|
|
97
991
|
|
|
98
992
|
declare class FlonkKYCServer {
|
|
99
|
-
static readonly version = "1.
|
|
993
|
+
static readonly version = "1.9.1";
|
|
100
994
|
private readonly http;
|
|
101
995
|
readonly webhooks: Webhooks;
|
|
102
996
|
constructor(options: FlonkKYCServerOptions);
|
|
@@ -105,14 +999,22 @@ declare class FlonkKYCServer {
|
|
|
105
999
|
updateSession(sessionId: string, params: UpdateSessionParams): Promise<SessionDetails>;
|
|
106
1000
|
}
|
|
107
1001
|
|
|
1002
|
+
/**
|
|
1003
|
+
* Stable, machine-branchable error codes returned by the API in the `code`
|
|
1004
|
+
* field of an error body. Open union (`| (string & {})`) so new codes don't
|
|
1005
|
+
* break consumers — branch on the ones you handle, fall through on the rest.
|
|
1006
|
+
*/
|
|
1007
|
+
type FlonkErrorCode = 'authentication_error' | 'invalid_publishable_key' | 'session_not_found' | 'session_expired' | 'session_invalid_state' | 'rate_limited' | 'validation_error' | 'api_error' | (string & {});
|
|
108
1008
|
declare class FlonkError extends Error {
|
|
109
|
-
readonly code:
|
|
1009
|
+
readonly code: FlonkErrorCode;
|
|
110
1010
|
readonly statusCode?: number | undefined;
|
|
111
|
-
constructor(message: string, code:
|
|
1011
|
+
constructor(message: string, code: FlonkErrorCode, statusCode?: number | undefined);
|
|
112
1012
|
}
|
|
113
1013
|
declare class FlonkAPIError extends FlonkError {
|
|
114
1014
|
readonly body?: unknown | undefined;
|
|
115
|
-
constructor(message: string, statusCode: number, body?: unknown | undefined
|
|
1015
|
+
constructor(message: string, statusCode: number, body?: unknown | undefined,
|
|
1016
|
+
/** The API's stable error code (from the response body), if it sent one. */
|
|
1017
|
+
code?: FlonkErrorCode);
|
|
116
1018
|
}
|
|
117
1019
|
declare class FlonkAuthenticationError extends FlonkError {
|
|
118
1020
|
constructor(message?: string);
|
|
@@ -124,4 +1026,4 @@ declare class FlonkWebhookSignatureError extends FlonkError {
|
|
|
124
1026
|
constructor(message?: string);
|
|
125
1027
|
}
|
|
126
1028
|
|
|
127
|
-
export { type CreateSessionParams, type DocumentType, FlonkAPIError, FlonkAuthenticationError, FlonkError, FlonkKYCServer, type FlonkKYCServerOptions, FlonkValidationError, FlonkWebhookSignatureError, type Session, type SessionDetails, type SessionStatus, type UpdateSessionParams, type WebhookEvent, type WebhookVerifyOptions, Webhooks, type WidgetLanguage };
|
|
1029
|
+
export { type CreateSessionParams, type DocumentType, FlonkAPIError, FlonkAuthenticationError, FlonkError, type FlonkErrorCode, FlonkKYCServer, type FlonkKYCServerOptions, FlonkValidationError, FlonkWebhookSignatureError, type Session, type SessionDetails, type SessionStatus, type UpdateSessionParams, type VerificationCompletedEvent, type VerificationStatusChangedEvent, type VerificationUpdatedEvent, type WebhookEvent, type WebhookEventType, type WebhookVerifyOptions, Webhooks, type WidgetLanguage };
|