chargeback-guard 2.0.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/LICENSE +21 -0
- package/README.md +311 -0
- package/docs/api.md +278 -0
- package/docs/architecture.md +281 -0
- package/docs/configuration.md +292 -0
- package/docs/getting-started.md +155 -0
- package/examples/advancedConfig.ts +123 -0
- package/examples/basicUsage.ts +98 -0
- package/examples/stripeIntegration.ts +106 -0
- package/package.json +181 -0
- package/src/ai/fraudDetection.ts +261 -0
- package/src/ai/patternRecognition.ts +218 -0
- package/src/analytics/dashboard.ts +195 -0
- package/src/analytics/metrics.ts +175 -0
- package/src/analytics/predictions.ts +135 -0
- package/src/analytics/reports.ts +221 -0
- package/src/api/controllers.ts +339 -0
- package/src/api/middleware.ts +172 -0
- package/src/api/routes.ts +141 -0
- package/src/config.ts +231 -0
- package/src/core/chargebackGuard.ts +616 -0
- package/src/core/eventEmitter.ts +118 -0
- package/src/core/lifecycle.ts +215 -0
- package/src/database/schema.ts +392 -0
- package/src/dispute/analyzer.ts +317 -0
- package/src/dispute/bankIntegration.ts +274 -0
- package/src/dispute/detector.ts +239 -0
- package/src/dispute/responseEngine.ts +440 -0
- package/src/evidence/collector.ts +426 -0
- package/src/evidence/encryption.ts +168 -0
- package/src/evidence/storage.ts +197 -0
- package/src/evidence/validator.ts +184 -0
- package/src/index.ts +43 -0
- package/src/integrations/paypal.ts +258 -0
- package/src/integrations/stripe.ts +280 -0
- package/src/integrations/webhook.ts +332 -0
- package/src/notifications/email.ts +161 -0
- package/src/notifications/inApp.ts +319 -0
- package/src/notifications/sms.ts +58 -0
- package/src/security/auth.ts +153 -0
- package/src/security/rateLimit.ts +77 -0
- package/src/security/validation.ts +166 -0
- package/src/server.ts +122 -0
- package/src/types/index.ts +790 -0
- package/src/utils/formatters.ts +72 -0
- package/src/utils/helpers.ts +193 -0
- package/src/utils/logger.ts +88 -0
- package/src/utils/validators.ts +39 -0
|
@@ -0,0 +1,790 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// CHARGEBACK GUARD — Core Type Definitions (Ultra Pro)
|
|
3
|
+
// All interfaces, enums, and shared types used across the pkg
|
|
4
|
+
// ============================================================
|
|
5
|
+
|
|
6
|
+
// ────────────────────────────────────────────────────────────
|
|
7
|
+
// ENUMS
|
|
8
|
+
// ────────────────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
export enum Environment {
|
|
11
|
+
DEVELOPMENT = 'development',
|
|
12
|
+
STAGING = 'staging',
|
|
13
|
+
PRODUCTION = 'production',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export enum PaymentProvider {
|
|
17
|
+
STRIPE = 'stripe',
|
|
18
|
+
PAYPAL = 'paypal',
|
|
19
|
+
SQUARE = 'square',
|
|
20
|
+
BRAINTREE = 'braintree',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export enum DisputeReason {
|
|
24
|
+
PRODUCT_NOT_RECEIVED = 'product_not_received',
|
|
25
|
+
PRODUCT_UNACCEPTABLE = 'product_unacceptable',
|
|
26
|
+
UNAUTHORIZED_TRANSACTION = 'unauthorized_transaction',
|
|
27
|
+
DUPLICATE_TRANSACTION = 'duplicate_transaction',
|
|
28
|
+
CREDIT_NOT_PROCESSED = 'credit_not_processed',
|
|
29
|
+
SUBSCRIPTION_CANCELLED = 'subscription_cancelled',
|
|
30
|
+
FRAUDULENT = 'fraudulent',
|
|
31
|
+
GENERAL = 'general',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export enum DisputeStatus {
|
|
35
|
+
NEEDS_RESPONSE = 'needs_response',
|
|
36
|
+
UNDER_REVIEW = 'under_review',
|
|
37
|
+
CHARGE_REFUNDED = 'charge_refunded',
|
|
38
|
+
WON = 'won',
|
|
39
|
+
LOST = 'lost',
|
|
40
|
+
WARNING_NEEDS_RESPONSE = 'warning_needs_response',
|
|
41
|
+
WARNING_UNDER_REVIEW = 'warning_under_review',
|
|
42
|
+
WARNING_CLOSED = 'warning_closed',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export enum RiskLevel {
|
|
46
|
+
VERY_LOW = 'very_low',
|
|
47
|
+
LOW = 'low',
|
|
48
|
+
MEDIUM = 'medium',
|
|
49
|
+
HIGH = 'high',
|
|
50
|
+
CRITICAL = 'critical',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export enum ConfidenceLevel {
|
|
54
|
+
VERY_HIGH = 'very_high',
|
|
55
|
+
HIGH = 'high',
|
|
56
|
+
MEDIUM = 'medium',
|
|
57
|
+
LOW = 'low',
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export enum EvidenceType {
|
|
61
|
+
DELIVERY_PROOF = 'delivery_proof',
|
|
62
|
+
DEVICE_FINGERPRINT = 'device_fingerprint',
|
|
63
|
+
CUSTOMER_COMMUNICATION = 'customer_communication',
|
|
64
|
+
TRANSACTION_LOG = 'transaction_log',
|
|
65
|
+
BEHAVIOR_ANALYSIS = 'behavior_analysis',
|
|
66
|
+
CUSTOMER_HISTORY = 'customer_history',
|
|
67
|
+
EMAIL_CONFIRMATION = 'email_confirmation',
|
|
68
|
+
PAYMENT_LOG = 'payment_log',
|
|
69
|
+
GEOLOCATION = 'geolocation',
|
|
70
|
+
BROWSER_SCREENSHOT = 'browser_screenshot',
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export enum NotificationChannel {
|
|
74
|
+
EMAIL = 'email',
|
|
75
|
+
SMS = 'sms',
|
|
76
|
+
WEBHOOK = 'webhook',
|
|
77
|
+
IN_APP = 'in_app',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export enum NotificationEvent {
|
|
81
|
+
PAYMENT_REGISTERED = 'payment:registered',
|
|
82
|
+
DISPUTE_DETECTED = 'dispute:detected',
|
|
83
|
+
DISPUTE_REPLIED = 'dispute:replied',
|
|
84
|
+
DISPUTE_WON = 'dispute:won',
|
|
85
|
+
DISPUTE_LOST = 'dispute:lost',
|
|
86
|
+
HIGH_RISK_TRANSACTION = 'transaction:high_risk',
|
|
87
|
+
FRAUD_DETECTED = 'fraud:detected',
|
|
88
|
+
ERROR = 'error',
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export enum SubscriptionPlan {
|
|
92
|
+
FREE = 'free',
|
|
93
|
+
STARTER = 'starter',
|
|
94
|
+
PRO = 'pro',
|
|
95
|
+
ENTERPRISE = 'enterprise',
|
|
96
|
+
CUSTOM = 'custom',
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ────────────────────────────────────────────────────────────
|
|
100
|
+
// CONFIGURATION INTERFACES
|
|
101
|
+
// ────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
export interface ChargebackGuardConfig {
|
|
104
|
+
apiKey: string;
|
|
105
|
+
webhookSecret?: string;
|
|
106
|
+
environment?: Environment;
|
|
107
|
+
autoReply?: boolean;
|
|
108
|
+
evidenceCollection?: boolean;
|
|
109
|
+
database?: DatabaseConfig;
|
|
110
|
+
redis?: RedisConfig;
|
|
111
|
+
notifications?: NotificationConfig;
|
|
112
|
+
security?: SecurityConfig;
|
|
113
|
+
ai?: AIConfig;
|
|
114
|
+
billing?: BillingConfig;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface DatabaseConfig {
|
|
118
|
+
type: 'sqlite' | 'postgresql' | 'mysql';
|
|
119
|
+
url: string;
|
|
120
|
+
poolMin?: number;
|
|
121
|
+
poolMax?: number;
|
|
122
|
+
debug?: boolean;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface RedisConfig {
|
|
126
|
+
url: string;
|
|
127
|
+
password?: string;
|
|
128
|
+
db?: number;
|
|
129
|
+
ttl?: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface NotificationConfig {
|
|
133
|
+
email?: EmailConfig;
|
|
134
|
+
sms?: SMSConfig;
|
|
135
|
+
webhooks?: WebhookConfig[];
|
|
136
|
+
channels?: NotificationChannel[];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface EmailConfig {
|
|
140
|
+
host: string;
|
|
141
|
+
port: number;
|
|
142
|
+
secure: boolean;
|
|
143
|
+
user: string;
|
|
144
|
+
pass: string;
|
|
145
|
+
fromName: string;
|
|
146
|
+
fromAddress: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface SMSConfig {
|
|
150
|
+
accountSid: string;
|
|
151
|
+
authToken: string;
|
|
152
|
+
phoneNumber: string;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface WebhookConfig {
|
|
156
|
+
url: string;
|
|
157
|
+
secret?: string;
|
|
158
|
+
events?: NotificationEvent[];
|
|
159
|
+
retries?: number;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface SecurityConfig {
|
|
163
|
+
jwtSecret: string;
|
|
164
|
+
jwtExpiresIn?: string;
|
|
165
|
+
encryptionKey: string;
|
|
166
|
+
bcryptRounds?: number;
|
|
167
|
+
rateLimit?: RateLimitConfig;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface RateLimitConfig {
|
|
171
|
+
windowMs: number;
|
|
172
|
+
maxRequests: number;
|
|
173
|
+
skipFailedRequests?: boolean;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface AIConfig {
|
|
177
|
+
openaiApiKey?: string;
|
|
178
|
+
modelPath?: string;
|
|
179
|
+
fraudThreshold?: number;
|
|
180
|
+
riskScoreHigh?: number;
|
|
181
|
+
riskScoreMedium?: number;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface BillingConfig {
|
|
185
|
+
plan?: SubscriptionPlan;
|
|
186
|
+
revenueSharePercentage?: number;
|
|
187
|
+
monthlyPrice?: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ────────────────────────────────────────────────────────────
|
|
191
|
+
// PAYMENT & ORDER INTERFACES
|
|
192
|
+
// ────────────────────────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
export interface PaymentData {
|
|
195
|
+
orderId: string;
|
|
196
|
+
amount: number;
|
|
197
|
+
currency: string;
|
|
198
|
+
customerEmail: string;
|
|
199
|
+
customerName?: string;
|
|
200
|
+
customerIp?: string;
|
|
201
|
+
userAgent?: string;
|
|
202
|
+
sessionData?: SessionData;
|
|
203
|
+
deviceFingerprint?: DeviceFingerprint;
|
|
204
|
+
shippingAddress?: Address;
|
|
205
|
+
billingAddress?: Address;
|
|
206
|
+
paymentMethod?: string;
|
|
207
|
+
cardLastFour?: string;
|
|
208
|
+
cardBrand?: string;
|
|
209
|
+
transactionId?: string;
|
|
210
|
+
provider?: PaymentProvider;
|
|
211
|
+
metadata?: Record<string, unknown>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface SessionData {
|
|
215
|
+
sessionId: string;
|
|
216
|
+
startedAt: string;
|
|
217
|
+
duration?: number;
|
|
218
|
+
pageViews?: PageView[];
|
|
219
|
+
clickTracking?: ClickEvent[];
|
|
220
|
+
formInteractions?: FormInteraction[];
|
|
221
|
+
mouseTracking?: MousePosition[];
|
|
222
|
+
scrollDepth?: number;
|
|
223
|
+
timeOnCheckout?: number;
|
|
224
|
+
referrer?: string;
|
|
225
|
+
utmSource?: string;
|
|
226
|
+
utmMedium?: string;
|
|
227
|
+
utmCampaign?: string;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface PageView {
|
|
231
|
+
url: string;
|
|
232
|
+
title?: string;
|
|
233
|
+
duration: number;
|
|
234
|
+
timestamp: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export interface ClickEvent {
|
|
238
|
+
element: string;
|
|
239
|
+
x: number;
|
|
240
|
+
y: number;
|
|
241
|
+
timestamp: string;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface FormInteraction {
|
|
245
|
+
field: string;
|
|
246
|
+
action: 'focus' | 'blur' | 'change' | 'submit';
|
|
247
|
+
timestamp: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface MousePosition {
|
|
251
|
+
x: number;
|
|
252
|
+
y: number;
|
|
253
|
+
timestamp: string;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface DeviceFingerprint {
|
|
257
|
+
screenResolution?: string;
|
|
258
|
+
timezone?: string;
|
|
259
|
+
language?: string;
|
|
260
|
+
plugins?: string[];
|
|
261
|
+
fonts?: string[];
|
|
262
|
+
webgl?: string;
|
|
263
|
+
canvas?: string;
|
|
264
|
+
cookiesEnabled?: boolean;
|
|
265
|
+
doNotTrack?: string;
|
|
266
|
+
platform?: string;
|
|
267
|
+
hardwareConcurrency?: number;
|
|
268
|
+
deviceMemory?: number;
|
|
269
|
+
touchPoints?: number;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export interface Address {
|
|
273
|
+
line1: string;
|
|
274
|
+
line2?: string;
|
|
275
|
+
city: string;
|
|
276
|
+
state?: string;
|
|
277
|
+
postalCode: string;
|
|
278
|
+
country: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export interface ShippingInfo {
|
|
282
|
+
address: Address;
|
|
283
|
+
carrier?: string;
|
|
284
|
+
trackingNumber?: string;
|
|
285
|
+
estimatedDelivery?: string;
|
|
286
|
+
shippedAt?: string;
|
|
287
|
+
deliveredAt?: string;
|
|
288
|
+
signature?: boolean;
|
|
289
|
+
signatureTimestamp?: string;
|
|
290
|
+
gpsCoordinates?: GeoCoordinates;
|
|
291
|
+
deliveryStatus?: 'pending' | 'in_transit' | 'delivered' | 'failed';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export interface GeoCoordinates {
|
|
295
|
+
lat: number;
|
|
296
|
+
lng: number;
|
|
297
|
+
accuracy?: number;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ────────────────────────────────────────────────────────────
|
|
301
|
+
// EVIDENCE INTERFACES
|
|
302
|
+
// ────────────────────────────────────────────────────────────
|
|
303
|
+
|
|
304
|
+
export interface Evidence {
|
|
305
|
+
collectionId: string;
|
|
306
|
+
orderId: string;
|
|
307
|
+
timestamp: string;
|
|
308
|
+
trustScore: number;
|
|
309
|
+
riskLevel: RiskLevel;
|
|
310
|
+
data: EvidenceData;
|
|
311
|
+
encrypted?: string[];
|
|
312
|
+
metadata?: Record<string, unknown>;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface EvidenceData {
|
|
316
|
+
customerData: CustomerEvidenceData;
|
|
317
|
+
transactionData: TransactionEvidenceData;
|
|
318
|
+
shippingData?: ShippingEvidenceData;
|
|
319
|
+
interactionData?: InteractionEvidenceData;
|
|
320
|
+
deviceFingerprint?: DeviceEvidenceData;
|
|
321
|
+
emailConfirmation?: EmailEvidenceData;
|
|
322
|
+
customerHistory?: CustomerHistoryData;
|
|
323
|
+
paymentLog?: PaymentLogData;
|
|
324
|
+
geolocation?: GeolocationData;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export interface CustomerEvidenceData {
|
|
328
|
+
ipAddress: string;
|
|
329
|
+
userAgent: string;
|
|
330
|
+
acceptLanguage?: string;
|
|
331
|
+
referer?: string;
|
|
332
|
+
deviceId: string;
|
|
333
|
+
email?: string;
|
|
334
|
+
countryCode?: string;
|
|
335
|
+
city?: string;
|
|
336
|
+
isp?: string;
|
|
337
|
+
ipReputation?: number;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export interface TransactionEvidenceData {
|
|
341
|
+
timestamp: string;
|
|
342
|
+
amount: number;
|
|
343
|
+
currency: string;
|
|
344
|
+
paymentMethod?: string;
|
|
345
|
+
cardLastFour?: string;
|
|
346
|
+
transactionId: string;
|
|
347
|
+
processorResponse?: string;
|
|
348
|
+
cvvMatch?: boolean;
|
|
349
|
+
avsMatch?: boolean;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export interface ShippingEvidenceData {
|
|
353
|
+
address?: Address;
|
|
354
|
+
zip?: string;
|
|
355
|
+
country?: string;
|
|
356
|
+
shippingDate?: string;
|
|
357
|
+
trackingNumber?: string;
|
|
358
|
+
estimatedDelivery?: string;
|
|
359
|
+
deliveryDate?: string;
|
|
360
|
+
signature?: boolean;
|
|
361
|
+
gpsCoordinates?: GeoCoordinates;
|
|
362
|
+
carrierVerification?: string;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface InteractionEvidenceData {
|
|
366
|
+
sessionDuration: number;
|
|
367
|
+
pageViews: PageView[];
|
|
368
|
+
clickTracking: ClickEvent[];
|
|
369
|
+
formInteractions: FormInteraction[];
|
|
370
|
+
timeOnCheckout: number;
|
|
371
|
+
mouseTracking?: MousePosition[];
|
|
372
|
+
scrollDepth?: number;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface DeviceEvidenceData {
|
|
376
|
+
screenResolution?: string;
|
|
377
|
+
timezone?: string;
|
|
378
|
+
language?: string;
|
|
379
|
+
plugins?: string[];
|
|
380
|
+
fonts?: string[];
|
|
381
|
+
webgl?: string;
|
|
382
|
+
canvas?: string;
|
|
383
|
+
fingerprint?: string;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
export interface EmailEvidenceData {
|
|
387
|
+
sentTo: string;
|
|
388
|
+
sentAt: string;
|
|
389
|
+
opened?: boolean;
|
|
390
|
+
openedAt?: string;
|
|
391
|
+
clickedLinks?: string[];
|
|
392
|
+
bouncedAt?: string;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export interface CustomerHistoryData {
|
|
396
|
+
accountCreatedAt: string;
|
|
397
|
+
accountAge: number;
|
|
398
|
+
previousPurchases: number;
|
|
399
|
+
previousDisputes: number;
|
|
400
|
+
riskScore: number;
|
|
401
|
+
trustScore: number;
|
|
402
|
+
loyaltyStatus?: string;
|
|
403
|
+
reviewsGiven?: number;
|
|
404
|
+
supportTickets?: number;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
export interface PaymentLogData {
|
|
408
|
+
attempts: number;
|
|
409
|
+
successful: number;
|
|
410
|
+
failed: number;
|
|
411
|
+
lastAttemptAt?: string;
|
|
412
|
+
methods?: string[];
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface GeolocationData {
|
|
416
|
+
ip: string;
|
|
417
|
+
country: string;
|
|
418
|
+
city: string;
|
|
419
|
+
timezone: string;
|
|
420
|
+
latitude?: number;
|
|
421
|
+
longitude?: number;
|
|
422
|
+
isp?: string;
|
|
423
|
+
org?: string;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// ────────────────────────────────────────────────────────────
|
|
427
|
+
// DISPUTE INTERFACES
|
|
428
|
+
// ────────────────────────────────────────────────────────────
|
|
429
|
+
|
|
430
|
+
export interface Dispute {
|
|
431
|
+
id: string;
|
|
432
|
+
orderId?: string;
|
|
433
|
+
amount: number;
|
|
434
|
+
currency?: string;
|
|
435
|
+
reason: DisputeReason;
|
|
436
|
+
status: DisputeStatus;
|
|
437
|
+
provider: PaymentProvider;
|
|
438
|
+
evidenceDueBy?: string;
|
|
439
|
+
createdAt: string;
|
|
440
|
+
updatedAt?: string;
|
|
441
|
+
metadata?: Record<string, unknown>;
|
|
442
|
+
evidence?: Record<string, unknown>;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export interface DisputeAnalysis {
|
|
446
|
+
disputeId: string;
|
|
447
|
+
riskLevel: RiskLevel;
|
|
448
|
+
confidenceScore: number;
|
|
449
|
+
deliveryProofStrength: number;
|
|
450
|
+
deviceConsistency: number;
|
|
451
|
+
customerReputationScore: number;
|
|
452
|
+
transactionNormality: number;
|
|
453
|
+
fraudProbability: number;
|
|
454
|
+
recommendedAction: 'fight' | 'accept' | 'review';
|
|
455
|
+
analysisReasons: string[];
|
|
456
|
+
analyzedAt: string;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export interface DisputeReply {
|
|
460
|
+
disputeId: string;
|
|
461
|
+
orderId?: string;
|
|
462
|
+
generatedAt: string;
|
|
463
|
+
evidenceItems: EvidenceItem[];
|
|
464
|
+
summary: ReplySummary;
|
|
465
|
+
caseArgument?: string;
|
|
466
|
+
attachments?: Attachment[];
|
|
467
|
+
bankFormat?: BankReplyFormat;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export interface EvidenceItem {
|
|
471
|
+
type: EvidenceType | string;
|
|
472
|
+
description: string;
|
|
473
|
+
data: Record<string, unknown>;
|
|
474
|
+
weight?: number;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
export interface ReplySummary {
|
|
478
|
+
trustScore: number;
|
|
479
|
+
confidenceLevel: ConfidenceLevel;
|
|
480
|
+
recommendation: string;
|
|
481
|
+
keyPoints?: string[];
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
export interface Attachment {
|
|
485
|
+
type: string;
|
|
486
|
+
name: string;
|
|
487
|
+
mimeType: string;
|
|
488
|
+
description: string;
|
|
489
|
+
base64Data?: string;
|
|
490
|
+
url?: string;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
export interface BankReplyFormat {
|
|
494
|
+
dispute_id: string;
|
|
495
|
+
evidence_items: EvidenceItem[];
|
|
496
|
+
merchant_reference: string;
|
|
497
|
+
submitted_at: string;
|
|
498
|
+
case_argument: string;
|
|
499
|
+
attachment_files?: Attachment[];
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// ────────────────────────────────────────────────────────────
|
|
503
|
+
// ANALYTICS INTERFACES
|
|
504
|
+
// ────────────────────────────────────────────────────────────
|
|
505
|
+
|
|
506
|
+
export interface ProtectionStats {
|
|
507
|
+
totalOrders: number;
|
|
508
|
+
totalDisputes: number;
|
|
509
|
+
resolvedDisputes: number;
|
|
510
|
+
wonDisputes: number;
|
|
511
|
+
lostDisputes: number;
|
|
512
|
+
pendingDisputes: number;
|
|
513
|
+
winRate: number;
|
|
514
|
+
totalMoneyRecovered: number;
|
|
515
|
+
totalMoneyLost: number;
|
|
516
|
+
averageResolutionTime: number;
|
|
517
|
+
chargebackRate: number;
|
|
518
|
+
estimatedSavings: number;
|
|
519
|
+
period?: StatsPeriod;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export interface StatsPeriod {
|
|
523
|
+
from: string;
|
|
524
|
+
to: string;
|
|
525
|
+
granularity: 'day' | 'week' | 'month' | 'year';
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export interface TimeSeriesPoint {
|
|
529
|
+
date: string;
|
|
530
|
+
value: number;
|
|
531
|
+
label?: string;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export interface DashboardMetrics {
|
|
535
|
+
realTime: RealTimeMetrics;
|
|
536
|
+
charts: ChartData;
|
|
537
|
+
alerts: AlertItem[];
|
|
538
|
+
topRisks: RiskItem[];
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export interface RealTimeMetrics {
|
|
542
|
+
activeDisputes: number;
|
|
543
|
+
pendingReplies: number;
|
|
544
|
+
lastHourTransactions: number;
|
|
545
|
+
suspiciousActivities: number;
|
|
546
|
+
systemHealth: 'healthy' | 'degraded' | 'down';
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export interface ChartData {
|
|
550
|
+
monthlyChargebacks: TimeSeriesPoint[];
|
|
551
|
+
recoveryRate: TimeSeriesPoint[];
|
|
552
|
+
disputesByReason: Record<string, number>;
|
|
553
|
+
riskDistribution: Record<string, number>;
|
|
554
|
+
costSavings: TimeSeriesPoint[];
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export interface AlertItem {
|
|
558
|
+
id: string;
|
|
559
|
+
severity: 'info' | 'warning' | 'critical';
|
|
560
|
+
message: string;
|
|
561
|
+
orderId?: string;
|
|
562
|
+
createdAt: string;
|
|
563
|
+
resolved: boolean;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export interface RiskItem {
|
|
567
|
+
orderId: string;
|
|
568
|
+
amount: number;
|
|
569
|
+
riskScore: number;
|
|
570
|
+
riskLevel: RiskLevel;
|
|
571
|
+
reason: string;
|
|
572
|
+
detectedAt: string;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// ────────────────────────────────────────────────────────────
|
|
576
|
+
// API INTERFACES
|
|
577
|
+
// ────────────────────────────────────────────────────────────
|
|
578
|
+
|
|
579
|
+
export interface ApiResponse<T = unknown> {
|
|
580
|
+
success: boolean;
|
|
581
|
+
data?: T;
|
|
582
|
+
error?: ApiError;
|
|
583
|
+
meta?: ApiMeta;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
export interface ApiError {
|
|
587
|
+
code: string;
|
|
588
|
+
message: string;
|
|
589
|
+
details?: Record<string, unknown>;
|
|
590
|
+
stack?: string;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
export interface ApiMeta {
|
|
594
|
+
timestamp: string;
|
|
595
|
+
requestId: string;
|
|
596
|
+
version: string;
|
|
597
|
+
pagination?: PaginationMeta;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
export interface PaginationMeta {
|
|
601
|
+
page: number;
|
|
602
|
+
limit: number;
|
|
603
|
+
total: number;
|
|
604
|
+
totalPages: number;
|
|
605
|
+
hasNext: boolean;
|
|
606
|
+
hasPrev: boolean;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export interface PaginationQuery {
|
|
610
|
+
page?: number;
|
|
611
|
+
limit?: number;
|
|
612
|
+
sortBy?: string;
|
|
613
|
+
sortOrder?: 'asc' | 'desc';
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
export interface FilterQuery extends PaginationQuery {
|
|
617
|
+
from?: string;
|
|
618
|
+
to?: string;
|
|
619
|
+
status?: string;
|
|
620
|
+
reason?: string;
|
|
621
|
+
provider?: string;
|
|
622
|
+
riskLevel?: string;
|
|
623
|
+
search?: string;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// ────────────────────────────────────────────────────────────
|
|
627
|
+
// NOTIFICATION INTERFACES
|
|
628
|
+
// ────────────────────────────────────────────────────────────
|
|
629
|
+
|
|
630
|
+
export interface NotificationPayload {
|
|
631
|
+
event: NotificationEvent;
|
|
632
|
+
channel: NotificationChannel;
|
|
633
|
+
recipient: NotificationRecipient;
|
|
634
|
+
data: Record<string, unknown>;
|
|
635
|
+
template?: string;
|
|
636
|
+
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
export interface NotificationRecipient {
|
|
640
|
+
email?: string;
|
|
641
|
+
phone?: string;
|
|
642
|
+
webhookUrl?: string;
|
|
643
|
+
userId?: string;
|
|
644
|
+
name?: string;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export interface NotificationResult {
|
|
648
|
+
success: boolean;
|
|
649
|
+
channel: NotificationChannel;
|
|
650
|
+
messageId?: string;
|
|
651
|
+
error?: string;
|
|
652
|
+
sentAt: string;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// ────────────────────────────────────────────────────────────
|
|
656
|
+
// ML / AI INTERFACES
|
|
657
|
+
// ────────────────────────────────────────────────────────────
|
|
658
|
+
|
|
659
|
+
export interface FraudFeatures {
|
|
660
|
+
deviceFingerprint: string;
|
|
661
|
+
ipReputation: number;
|
|
662
|
+
customerAge: number;
|
|
663
|
+
purchaseHistory: number;
|
|
664
|
+
behavioralScore: number;
|
|
665
|
+
geoRiskScore: number;
|
|
666
|
+
velocityScore: number;
|
|
667
|
+
cardRiskScore: number;
|
|
668
|
+
emailRiskScore: number;
|
|
669
|
+
timeRiskScore: number;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
export interface FraudPrediction {
|
|
673
|
+
isFraud: boolean;
|
|
674
|
+
probability: number;
|
|
675
|
+
riskScore: number;
|
|
676
|
+
riskLevel: RiskLevel;
|
|
677
|
+
features: Partial<FraudFeatures>;
|
|
678
|
+
modelVersion: string;
|
|
679
|
+
predictedAt: string;
|
|
680
|
+
explanation?: string[];
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export interface PatternResult {
|
|
684
|
+
patternType: string;
|
|
685
|
+
detected: boolean;
|
|
686
|
+
confidence: number;
|
|
687
|
+
evidence: string[];
|
|
688
|
+
severity: 'low' | 'medium' | 'high';
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// ────────────────────────────────────────────────────────────
|
|
692
|
+
// WEBHOOK INTERFACES
|
|
693
|
+
// ────────────────────────────────────────────────────────────
|
|
694
|
+
|
|
695
|
+
export interface WebhookEvent {
|
|
696
|
+
id: string;
|
|
697
|
+
type: string;
|
|
698
|
+
provider: PaymentProvider;
|
|
699
|
+
created: number;
|
|
700
|
+
data: {
|
|
701
|
+
object: Record<string, unknown>;
|
|
702
|
+
previous_attributes?: Record<string, unknown>;
|
|
703
|
+
};
|
|
704
|
+
livemode?: boolean;
|
|
705
|
+
request?: {
|
|
706
|
+
id: string | null;
|
|
707
|
+
idempotency_key: string | null;
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
export interface ProcessedWebhookResult {
|
|
712
|
+
eventId: string;
|
|
713
|
+
type: string;
|
|
714
|
+
processed: boolean;
|
|
715
|
+
action?: string;
|
|
716
|
+
error?: string;
|
|
717
|
+
processedAt: string;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// ────────────────────────────────────────────────────────────
|
|
721
|
+
// DATABASE MODEL INTERFACES
|
|
722
|
+
// ────────────────────────────────────────────────────────────
|
|
723
|
+
|
|
724
|
+
export interface OrderRecord {
|
|
725
|
+
id: number;
|
|
726
|
+
orderId: string;
|
|
727
|
+
merchantId: string;
|
|
728
|
+
amount: number;
|
|
729
|
+
currency: string;
|
|
730
|
+
customerEmail: string;
|
|
731
|
+
status: string;
|
|
732
|
+
provider: PaymentProvider;
|
|
733
|
+
registeredAt: string;
|
|
734
|
+
createdAt: string;
|
|
735
|
+
updatedAt: string;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
export interface EvidenceRecord {
|
|
739
|
+
id: number;
|
|
740
|
+
orderId: string;
|
|
741
|
+
collectionId: string;
|
|
742
|
+
evidenceJson: string;
|
|
743
|
+
trustScore: number;
|
|
744
|
+
riskLevel: RiskLevel;
|
|
745
|
+
collectedAt: string;
|
|
746
|
+
createdAt: string;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
export interface DisputeRecord {
|
|
750
|
+
id: number;
|
|
751
|
+
disputeId: string;
|
|
752
|
+
orderId: string;
|
|
753
|
+
amount: number;
|
|
754
|
+
reason: DisputeReason;
|
|
755
|
+
status: DisputeStatus;
|
|
756
|
+
provider: PaymentProvider;
|
|
757
|
+
replyJson?: string;
|
|
758
|
+
replySubmittedAt?: string;
|
|
759
|
+
resolvedAt?: string;
|
|
760
|
+
wonAt?: string;
|
|
761
|
+
lostAt?: string;
|
|
762
|
+
evidenceDueBy?: string;
|
|
763
|
+
createdAt: string;
|
|
764
|
+
updatedAt: string;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
export interface MerchantRecord {
|
|
768
|
+
id: number;
|
|
769
|
+
merchantId: string;
|
|
770
|
+
name: string;
|
|
771
|
+
email: string;
|
|
772
|
+
apiKey: string;
|
|
773
|
+
plan: SubscriptionPlan;
|
|
774
|
+
webhookUrl?: string;
|
|
775
|
+
settings?: string;
|
|
776
|
+
isActive: boolean;
|
|
777
|
+
createdAt: string;
|
|
778
|
+
updatedAt: string;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// ────────────────────────────────────────────────────────────
|
|
782
|
+
// UTILITY TYPE HELPERS
|
|
783
|
+
// ────────────────────────────────────────────────────────────
|
|
784
|
+
|
|
785
|
+
export type AsyncResult<T> = Promise<ApiResponse<T>>;
|
|
786
|
+
export type Nullable<T> = T | null;
|
|
787
|
+
export type Optional<T> = T | undefined;
|
|
788
|
+
export type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] };
|
|
789
|
+
export type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =
|
|
790
|
+
Pick<T, Exclude<keyof T, Keys>> & { [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>> }[Keys];
|