@tapsilat/tapsilat-js 1.0.2 → 1.0.4
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/CHANGELOG.md +14 -0
- package/README.md +6 -12
- package/dist/TapsilatSDK.d.ts +202 -173
- package/dist/TapsilatSDK.d.ts.map +1 -1
- package/dist/config/ConfigManager.d.ts +77 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/errors/TapsilatError.d.ts +84 -1
- package/dist/errors/TapsilatError.d.ts.map +1 -1
- package/dist/http/HttpClient.d.ts +126 -27
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/http/interceptors.d.ts +117 -1
- package/dist/http/interceptors.d.ts.map +1 -1
- package/dist/index.d.ts +880 -228
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +948 -294
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +948 -293
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +545 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/index.d.ts +47 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/validators.d.ts +74 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/types.d.ts +0 -401
- package/dist/types.d.ts.map +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @category Errors
|
|
5
|
+
* @summary Base error class for Tapsilat SDK
|
|
6
|
+
* @description Foundation error class for all Tapsilat-specific errors with error code and details support
|
|
7
|
+
* @class TapsilatError
|
|
8
|
+
* @extends Error
|
|
9
|
+
*/
|
|
1
10
|
class TapsilatError extends Error {
|
|
2
11
|
code;
|
|
3
12
|
details;
|
|
13
|
+
/**
|
|
14
|
+
* @summary Creates a new TapsilatError instance
|
|
15
|
+
* @description Initializes base error with message, code and optional details
|
|
16
|
+
*
|
|
17
|
+
* @param message - Human-readable error message
|
|
18
|
+
* @param code - Error code for programmatic identification
|
|
19
|
+
* @param details - Optional additional error context
|
|
20
|
+
*/
|
|
4
21
|
constructor(message, code, details) {
|
|
5
22
|
super(message);
|
|
6
23
|
this.name = 'TapsilatError';
|
|
@@ -11,32 +28,96 @@ class TapsilatError extends Error {
|
|
|
11
28
|
Error.captureStackTrace(this, TapsilatError);
|
|
12
29
|
}
|
|
13
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* @summary Creates a TapsilatError from an API error response
|
|
33
|
+
* @description Factory method to convert API error format to a TapsilatError instance
|
|
34
|
+
*
|
|
35
|
+
* @param apiError - API error object from response
|
|
36
|
+
* @returns New TapsilatError instance with properties from API error
|
|
37
|
+
*/
|
|
14
38
|
static fromAPIError(apiError) {
|
|
15
39
|
return new TapsilatError(apiError.message, apiError.code, apiError.details);
|
|
16
40
|
}
|
|
17
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* @category Errors
|
|
44
|
+
* @summary Network-related error class for HTTP issues
|
|
45
|
+
* @description Error class for network and HTTP-specific problems including status codes
|
|
46
|
+
* @class TapsilatNetworkError
|
|
47
|
+
* @extends TapsilatError
|
|
48
|
+
*/
|
|
18
49
|
class TapsilatNetworkError extends TapsilatError {
|
|
19
50
|
statusCode;
|
|
51
|
+
/**
|
|
52
|
+
* @summary Creates a new network error instance
|
|
53
|
+
* @description Initializes network error with message, code, status code and optional details
|
|
54
|
+
*
|
|
55
|
+
* @param message - Human-readable error message
|
|
56
|
+
* @param code - Error code for programmatic identification
|
|
57
|
+
* @param statusCode - HTTP status code if applicable
|
|
58
|
+
* @param details - Optional additional error context
|
|
59
|
+
*/
|
|
20
60
|
constructor(message, code, statusCode, details) {
|
|
21
61
|
super(message, code, details);
|
|
22
62
|
this.name = 'TapsilatNetworkError';
|
|
23
63
|
this.statusCode = statusCode;
|
|
24
64
|
}
|
|
25
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* @category Errors
|
|
68
|
+
* @summary Error class for validation failures
|
|
69
|
+
* @description Error class for data validation issues with field-specific error details
|
|
70
|
+
* @class TapsilatValidationError
|
|
71
|
+
* @extends TapsilatError
|
|
72
|
+
*/
|
|
26
73
|
class TapsilatValidationError extends TapsilatError {
|
|
74
|
+
/**
|
|
75
|
+
* @summary Creates a new validation error instance
|
|
76
|
+
* @description Initializes validation error with message and optional field-specific details
|
|
77
|
+
*
|
|
78
|
+
* @param message - Human-readable error message
|
|
79
|
+
* @param details - Optional field-specific validation errors
|
|
80
|
+
*/
|
|
27
81
|
constructor(message, details) {
|
|
28
82
|
super(message, 'VALIDATION_ERROR', details);
|
|
29
83
|
this.name = 'TapsilatValidationError';
|
|
30
84
|
}
|
|
31
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* @category Errors
|
|
88
|
+
* @summary Error class for authentication issues
|
|
89
|
+
* @description Error class for problems related to API keys, authentication tokens, or permissions
|
|
90
|
+
* @class TapsilatAuthenticationError
|
|
91
|
+
* @extends TapsilatError
|
|
92
|
+
*/
|
|
32
93
|
class TapsilatAuthenticationError extends TapsilatError {
|
|
94
|
+
/**
|
|
95
|
+
* @summary Creates a new authentication error instance
|
|
96
|
+
* @description Initializes authentication error with an optional custom message
|
|
97
|
+
*
|
|
98
|
+
* @param message - Human-readable error message (defaults to 'Authentication failed')
|
|
99
|
+
*/
|
|
33
100
|
constructor(message = 'Authentication failed') {
|
|
34
101
|
super(message, 'AUTHENTICATION_ERROR');
|
|
35
102
|
this.name = 'TapsilatAuthenticationError';
|
|
36
103
|
}
|
|
37
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* @category Errors
|
|
107
|
+
* @summary Error class for rate limit exceeded issues
|
|
108
|
+
* @description Error class for API rate limiting with information about when to retry
|
|
109
|
+
* @class TapsilatRateLimitError
|
|
110
|
+
* @extends TapsilatError
|
|
111
|
+
*/
|
|
38
112
|
class TapsilatRateLimitError extends TapsilatError {
|
|
39
113
|
retryAfter;
|
|
114
|
+
/**
|
|
115
|
+
* @summary Creates a new rate limit error instance
|
|
116
|
+
* @description Initializes rate limit error with message and optional retry-after seconds
|
|
117
|
+
*
|
|
118
|
+
* @param message - Human-readable error message (defaults to 'Rate limit exceeded')
|
|
119
|
+
* @param retryAfter - Optional seconds to wait before retrying
|
|
120
|
+
*/
|
|
40
121
|
constructor(message = 'Rate limit exceeded', retryAfter) {
|
|
41
122
|
super(message, 'RATE_LIMIT_ERROR');
|
|
42
123
|
this.name = 'TapsilatRateLimitError';
|
|
@@ -44,20 +125,52 @@ class TapsilatRateLimitError extends TapsilatError {
|
|
|
44
125
|
}
|
|
45
126
|
}
|
|
46
127
|
|
|
128
|
+
/**
|
|
129
|
+
* @category HTTP
|
|
130
|
+
* @summary Central registry and execution engine for all HTTP interceptors
|
|
131
|
+
* @description Maintains lists of request, response and error interceptors and provides methods to execute them in sequence
|
|
132
|
+
* @class InterceptorManager
|
|
133
|
+
*/
|
|
47
134
|
class InterceptorManager {
|
|
48
135
|
requestInterceptors = [];
|
|
49
136
|
responseInterceptors = [];
|
|
50
137
|
errorInterceptors = [];
|
|
51
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Adds a request interceptor to the chain
|
|
140
|
+
*
|
|
141
|
+
* @summary Register a new request interceptor function
|
|
142
|
+
* @description Adds a new interceptor to process requests before they are sent
|
|
143
|
+
*
|
|
144
|
+
* @param interceptor - The request interceptor function to add
|
|
145
|
+
* @returns The index of the added interceptor (can be used to remove it later)
|
|
146
|
+
*/
|
|
52
147
|
addRequestInterceptor(interceptor) {
|
|
53
148
|
this.requestInterceptors.push(interceptor);
|
|
54
149
|
return this.requestInterceptors.length - 1;
|
|
55
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Removes a previously added request interceptor
|
|
153
|
+
*
|
|
154
|
+
* @summary Unregister a request interceptor by its ID
|
|
155
|
+
* @description Removes the request interceptor at the specified position
|
|
156
|
+
*
|
|
157
|
+
* @param id - The index of the interceptor to remove
|
|
158
|
+
*/
|
|
56
159
|
removeRequestInterceptor(id) {
|
|
57
160
|
if (this.requestInterceptors[id]) {
|
|
58
161
|
delete this.requestInterceptors[id];
|
|
59
162
|
}
|
|
60
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Runs all registered request interceptors in sequence
|
|
166
|
+
*
|
|
167
|
+
* @summary Process a request through all interceptors
|
|
168
|
+
* @description Executes each registered request interceptor in order, passing modified url and options to each
|
|
169
|
+
*
|
|
170
|
+
* @param url - The initial request URL
|
|
171
|
+
* @param options - The initial request options
|
|
172
|
+
* @returns Modified URL and options after all interceptors have processed them
|
|
173
|
+
*/
|
|
61
174
|
async executeRequestInterceptors(url, options) {
|
|
62
175
|
let currentUrl = url;
|
|
63
176
|
let currentOptions = options;
|
|
@@ -70,16 +183,36 @@ class InterceptorManager {
|
|
|
70
183
|
}
|
|
71
184
|
return { url: currentUrl, options: currentOptions };
|
|
72
185
|
}
|
|
73
|
-
|
|
186
|
+
/**
|
|
187
|
+
* @summary Register a new response interceptor function
|
|
188
|
+
* @description Adds a new interceptor to process responses before they are returned to the caller
|
|
189
|
+
*
|
|
190
|
+
* @param interceptor - The response interceptor function to add
|
|
191
|
+
* @returns The index of the added interceptor (can be used to remove it later)
|
|
192
|
+
*/
|
|
74
193
|
addResponseInterceptor(interceptor) {
|
|
75
194
|
this.responseInterceptors.push(interceptor);
|
|
76
195
|
return this.responseInterceptors.length - 1;
|
|
77
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* @summary Unregister a response interceptor by its ID
|
|
199
|
+
* @description Removes the response interceptor at the specified position
|
|
200
|
+
*
|
|
201
|
+
* @param id - The index of the interceptor to remove
|
|
202
|
+
*/
|
|
78
203
|
removeResponseInterceptor(id) {
|
|
79
204
|
if (this.responseInterceptors[id]) {
|
|
80
205
|
delete this.responseInterceptors[id];
|
|
81
206
|
}
|
|
82
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* @summary Process a response through all interceptors
|
|
210
|
+
* @description Executes each registered response interceptor in order
|
|
211
|
+
*
|
|
212
|
+
* @param response - The API response to process
|
|
213
|
+
* @param request - The original request information
|
|
214
|
+
* @returns Modified response after all interceptors have processed it
|
|
215
|
+
*/
|
|
83
216
|
async executeResponseInterceptors(response, request) {
|
|
84
217
|
let currentResponse = response;
|
|
85
218
|
for (const interceptor of this.responseInterceptors) {
|
|
@@ -89,16 +222,36 @@ class InterceptorManager {
|
|
|
89
222
|
}
|
|
90
223
|
return currentResponse;
|
|
91
224
|
}
|
|
92
|
-
|
|
225
|
+
/**
|
|
226
|
+
* @summary Register a new error interceptor function
|
|
227
|
+
* @description Adds a new interceptor to process errors before they are thrown
|
|
228
|
+
*
|
|
229
|
+
* @param interceptor - The error interceptor function to add
|
|
230
|
+
* @returns The index of the added interceptor (can be used to remove it later)
|
|
231
|
+
*/
|
|
93
232
|
addErrorInterceptor(interceptor) {
|
|
94
233
|
this.errorInterceptors.push(interceptor);
|
|
95
234
|
return this.errorInterceptors.length - 1;
|
|
96
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* @summary Unregister an error interceptor by its ID
|
|
238
|
+
* @description Removes the error interceptor at the specified position
|
|
239
|
+
*
|
|
240
|
+
* @param id - The index of the interceptor to remove
|
|
241
|
+
*/
|
|
97
242
|
removeErrorInterceptor(id) {
|
|
98
243
|
if (this.errorInterceptors[id]) {
|
|
99
244
|
delete this.errorInterceptors[id];
|
|
100
245
|
}
|
|
101
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* @summary Process an error through all interceptors
|
|
249
|
+
* @description Executes each registered error interceptor in order until one handles the error
|
|
250
|
+
*
|
|
251
|
+
* @param error - The error that occurred during the request
|
|
252
|
+
* @param request - The original request information
|
|
253
|
+
* @returns Either a recovery response or throws the error if no interceptors handle it
|
|
254
|
+
*/
|
|
102
255
|
async executeErrorInterceptors(error, request) {
|
|
103
256
|
for (const interceptor of this.errorInterceptors) {
|
|
104
257
|
if (interceptor) {
|
|
@@ -114,7 +267,10 @@ class InterceptorManager {
|
|
|
114
267
|
// If no interceptor handled the error, re-throw
|
|
115
268
|
throw error;
|
|
116
269
|
}
|
|
117
|
-
|
|
270
|
+
/**
|
|
271
|
+
* @summary Remove all registered interceptors
|
|
272
|
+
* @description Clears all request, response, and error interceptors at once
|
|
273
|
+
*/
|
|
118
274
|
clear() {
|
|
119
275
|
this.requestInterceptors = [];
|
|
120
276
|
this.responseInterceptors = [];
|
|
@@ -123,8 +279,10 @@ class InterceptorManager {
|
|
|
123
279
|
}
|
|
124
280
|
|
|
125
281
|
/**
|
|
126
|
-
* HTTP
|
|
127
|
-
*
|
|
282
|
+
* @category HTTP
|
|
283
|
+
* @summary HTTP Client for making API requests to Tapsilat services
|
|
284
|
+
* @description Provides a robust client with comprehensive error handling,
|
|
285
|
+
* retry logic, and request/response interceptors for interacting with the Tapsilat API
|
|
128
286
|
*
|
|
129
287
|
* @example
|
|
130
288
|
* ```typescript
|
|
@@ -135,10 +293,17 @@ class InterceptorManager {
|
|
|
135
293
|
*
|
|
136
294
|
* const data = await client.get<UserResponse>('/users/123');
|
|
137
295
|
* ```
|
|
296
|
+
* @class HttpClient
|
|
138
297
|
*/
|
|
139
298
|
class HttpClient {
|
|
140
299
|
config;
|
|
141
300
|
interceptors = new InterceptorManager();
|
|
301
|
+
/**
|
|
302
|
+
* @summary Creates a new HTTP client instance
|
|
303
|
+
* @description Initializes the HTTP client with the provided configuration
|
|
304
|
+
*
|
|
305
|
+
* @param config - The configuration for the Tapsilat API client
|
|
306
|
+
*/
|
|
142
307
|
constructor(config) {
|
|
143
308
|
this.config = config;
|
|
144
309
|
}
|
|
@@ -158,7 +323,9 @@ class HttpClient {
|
|
|
158
323
|
return this.request("DELETE", url, undefined, config);
|
|
159
324
|
}
|
|
160
325
|
/**
|
|
161
|
-
*
|
|
326
|
+
* @category HTTP Client
|
|
327
|
+
* @summary Core request method with comprehensive error handling and retry logic
|
|
328
|
+
* @description Handles all HTTP requests with error handling, retries, and interceptors
|
|
162
329
|
*
|
|
163
330
|
* @param method - HTTP method to use
|
|
164
331
|
* @param url - Request URL (relative to baseURL)
|
|
@@ -209,7 +376,14 @@ class HttpClient {
|
|
|
209
376
|
}
|
|
210
377
|
}
|
|
211
378
|
/**
|
|
212
|
-
*
|
|
379
|
+
* @category HTTP Client Internals
|
|
380
|
+
* @summary Makes the actual HTTP request with timeout handling
|
|
381
|
+
* @description Performs the fetch request with timeout handling and abort controller
|
|
382
|
+
*
|
|
383
|
+
* @param url - Full URL to request
|
|
384
|
+
* @param options - Fetch request options
|
|
385
|
+
* @param timeout - Optional timeout in milliseconds
|
|
386
|
+
* @returns Promise resolving to API response
|
|
213
387
|
*/
|
|
214
388
|
async makeRequest(url, options, timeout) {
|
|
215
389
|
const controller = new AbortController();
|
|
@@ -241,7 +415,12 @@ class HttpClient {
|
|
|
241
415
|
}
|
|
242
416
|
}
|
|
243
417
|
/**
|
|
244
|
-
*
|
|
418
|
+
* @category HTTP Client Internals
|
|
419
|
+
* @summary Processes the fetch response and converts to APIResponse format
|
|
420
|
+
* @description Parses the response and formats it according to the APIResponse interface
|
|
421
|
+
*
|
|
422
|
+
* @param response - The raw fetch Response object
|
|
423
|
+
* @returns Processed API response
|
|
245
424
|
*/
|
|
246
425
|
async processResponse(response) {
|
|
247
426
|
const contentType = response.headers.get("content-type");
|
|
@@ -277,7 +456,13 @@ class HttpClient {
|
|
|
277
456
|
};
|
|
278
457
|
}
|
|
279
458
|
/**
|
|
280
|
-
*
|
|
459
|
+
* @category HTTP Client Internals
|
|
460
|
+
* @summary Creates appropriate error based on response status and data
|
|
461
|
+
* @description Maps HTTP status codes to specific Tapsilat error types
|
|
462
|
+
*
|
|
463
|
+
* @param response - The raw fetch Response object
|
|
464
|
+
* @param data - The parsed response data
|
|
465
|
+
* @returns Appropriate TapsilatError subclass instance
|
|
281
466
|
*/
|
|
282
467
|
createErrorFromResponse(response, data) {
|
|
283
468
|
const status = response.status;
|
|
@@ -309,7 +494,12 @@ class HttpClient {
|
|
|
309
494
|
}
|
|
310
495
|
}
|
|
311
496
|
/**
|
|
312
|
-
*
|
|
497
|
+
* @category HTTP Client Internals
|
|
498
|
+
* @summary Extracts error message from response data
|
|
499
|
+
* @description Attempts to find an error message in various locations within the response
|
|
500
|
+
*
|
|
501
|
+
* @param data - The parsed response data
|
|
502
|
+
* @returns Error message if found
|
|
313
503
|
*/
|
|
314
504
|
extractErrorMessage(data) {
|
|
315
505
|
if (typeof data === "string") {
|
|
@@ -322,7 +512,12 @@ class HttpClient {
|
|
|
322
512
|
return undefined;
|
|
323
513
|
}
|
|
324
514
|
/**
|
|
325
|
-
*
|
|
515
|
+
* @category HTTP Client Internals
|
|
516
|
+
* @summary Extracts validation details from error response
|
|
517
|
+
* @description Parses field-specific validation errors from the API response
|
|
518
|
+
*
|
|
519
|
+
* @param data - The parsed response data
|
|
520
|
+
* @returns Object mapping field names to error messages
|
|
326
521
|
*/
|
|
327
522
|
extractValidationDetails(data) {
|
|
328
523
|
if (data && typeof data === "object") {
|
|
@@ -332,7 +527,12 @@ class HttpClient {
|
|
|
332
527
|
return undefined;
|
|
333
528
|
}
|
|
334
529
|
/**
|
|
335
|
-
*
|
|
530
|
+
* @category HTTP Client Internals
|
|
531
|
+
* @summary Extracts rate limit information from response headers
|
|
532
|
+
* @description Reads and parses rate limiting headers from the API response
|
|
533
|
+
*
|
|
534
|
+
* @param response - The raw fetch Response object
|
|
535
|
+
* @returns Rate limit information including limits and reset time
|
|
336
536
|
*/
|
|
337
537
|
extractRateLimitInfo(response) {
|
|
338
538
|
const limit = response.headers.get("x-ratelimit-limit");
|
|
@@ -345,10 +545,19 @@ class HttpClient {
|
|
|
345
545
|
};
|
|
346
546
|
}
|
|
347
547
|
/**
|
|
348
|
-
*
|
|
548
|
+
* @category HTTP Client Internals
|
|
549
|
+
* @summary Builds the complete URL for the request
|
|
550
|
+
* @description Constructs the full URL with base URL and query parameters
|
|
551
|
+
*
|
|
552
|
+
* @param url - The endpoint path or full URL
|
|
553
|
+
* @param customBaseURL - Optional override for the base URL
|
|
554
|
+
* @param params - Optional query parameters
|
|
555
|
+
* @returns Complete request URL
|
|
349
556
|
*/
|
|
350
557
|
buildUrl(url, customBaseURL, params) {
|
|
351
|
-
const baseURL = customBaseURL ||
|
|
558
|
+
const baseURL = customBaseURL ||
|
|
559
|
+
this.config.baseURL ||
|
|
560
|
+
"https://acquiring.tapsilat.dev/api/v1";
|
|
352
561
|
if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
353
562
|
return url;
|
|
354
563
|
}
|
|
@@ -371,7 +580,14 @@ class HttpClient {
|
|
|
371
580
|
return fullUrl;
|
|
372
581
|
}
|
|
373
582
|
/**
|
|
374
|
-
*
|
|
583
|
+
* @category HTTP Client Internals
|
|
584
|
+
* @summary Builds RequestInit options for the fetch request
|
|
585
|
+
* @description Prepares headers and request configuration for fetch API
|
|
586
|
+
*
|
|
587
|
+
* @param method - The HTTP method to use
|
|
588
|
+
* @param body - Optional request body
|
|
589
|
+
* @param config - Additional request configuration
|
|
590
|
+
* @returns Configured RequestInit object for fetch
|
|
375
591
|
*/
|
|
376
592
|
async buildRequestOptions(method, body, config) {
|
|
377
593
|
const headers = new Headers({
|
|
@@ -406,7 +622,12 @@ class HttpClient {
|
|
|
406
622
|
return options;
|
|
407
623
|
}
|
|
408
624
|
/**
|
|
409
|
-
*
|
|
625
|
+
* @category HTTP Client Internals
|
|
626
|
+
* @summary Determines if an error should prevent retrying
|
|
627
|
+
* @description Checks error types to decide if retry attempts should be aborted
|
|
628
|
+
*
|
|
629
|
+
* @param error - The error that occurred
|
|
630
|
+
* @returns Whether retry should be prevented for this error
|
|
410
631
|
*/
|
|
411
632
|
shouldNotRetry(error) {
|
|
412
633
|
// Don't retry authentication, validation, or client errors
|
|
@@ -415,7 +636,12 @@ class HttpClient {
|
|
|
415
636
|
(error instanceof TapsilatError && error.code === "NOT_FOUND"));
|
|
416
637
|
}
|
|
417
638
|
/**
|
|
418
|
-
*
|
|
639
|
+
* @category HTTP Client Internals
|
|
640
|
+
* @summary Calculates retry delay with exponential backoff
|
|
641
|
+
* @description Implements exponential backoff with jitter for retry attempts
|
|
642
|
+
*
|
|
643
|
+
* @param attempt - The current retry attempt number (0-indexed)
|
|
644
|
+
* @returns Delay in milliseconds before next retry
|
|
419
645
|
*/
|
|
420
646
|
calculateRetryDelay(attempt) {
|
|
421
647
|
const baseDelay = 1000; // 1 second
|
|
@@ -425,14 +651,21 @@ class HttpClient {
|
|
|
425
651
|
return delay + Math.random() * 1000;
|
|
426
652
|
}
|
|
427
653
|
/**
|
|
428
|
-
*
|
|
654
|
+
* @category HTTP Client Internals
|
|
655
|
+
* @summary Utility method to create delay
|
|
656
|
+
* @description Creates a promise that resolves after the specified time
|
|
657
|
+
*
|
|
658
|
+
* @param ms - Delay time in milliseconds
|
|
659
|
+
* @returns Promise that resolves after the delay
|
|
429
660
|
*/
|
|
430
661
|
delay(ms) {
|
|
431
662
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
432
663
|
}
|
|
433
664
|
// Interceptor management methods
|
|
434
665
|
/**
|
|
435
|
-
*
|
|
666
|
+
* @category Interceptors
|
|
667
|
+
* @summary Gets the interceptor manager for advanced request/response handling
|
|
668
|
+
* @description Provides access to the internal interceptor manager for custom handling
|
|
436
669
|
*
|
|
437
670
|
* @returns InterceptorManager instance
|
|
438
671
|
*/
|
|
@@ -440,7 +673,9 @@ class HttpClient {
|
|
|
440
673
|
return this.interceptors;
|
|
441
674
|
}
|
|
442
675
|
/**
|
|
443
|
-
*
|
|
676
|
+
* @category Interceptors
|
|
677
|
+
* @summary Adds a request interceptor
|
|
678
|
+
* @description Registers a function to intercept and modify requests before they are sent
|
|
444
679
|
*
|
|
445
680
|
* @param interceptor - Request interceptor function
|
|
446
681
|
* @returns Interceptor ID for removal
|
|
@@ -449,7 +684,9 @@ class HttpClient {
|
|
|
449
684
|
return this.interceptors.addRequestInterceptor(interceptor);
|
|
450
685
|
}
|
|
451
686
|
/**
|
|
452
|
-
*
|
|
687
|
+
* @category Interceptors
|
|
688
|
+
* @summary Adds a response interceptor
|
|
689
|
+
* @description Registers a function to intercept and modify responses before they are returned
|
|
453
690
|
*
|
|
454
691
|
* @param interceptor - Response interceptor function
|
|
455
692
|
* @returns Interceptor ID for removal
|
|
@@ -458,7 +695,9 @@ class HttpClient {
|
|
|
458
695
|
return this.interceptors.addResponseInterceptor(interceptor);
|
|
459
696
|
}
|
|
460
697
|
/**
|
|
461
|
-
*
|
|
698
|
+
* @category Interceptors
|
|
699
|
+
* @summary Adds an error interceptor
|
|
700
|
+
* @description Registers a function to intercept and potentially recover from errors
|
|
462
701
|
*
|
|
463
702
|
* @param interceptor - Error interceptor function
|
|
464
703
|
* @returns Interceptor ID for removal
|
|
@@ -468,43 +707,108 @@ class HttpClient {
|
|
|
468
707
|
}
|
|
469
708
|
}
|
|
470
709
|
|
|
471
|
-
//
|
|
710
|
+
// TYPE GUARDS
|
|
711
|
+
// Summary: Type guards for payment method validation
|
|
712
|
+
// Description: Checks if a value matches the allowed payment method types
|
|
472
713
|
/**
|
|
473
714
|
* Type guard to check if a value is a valid PaymentMethod
|
|
715
|
+
*
|
|
716
|
+
* @summary Validates a value against supported payment methods
|
|
717
|
+
* @description Checks if provided value is a string and matches one of the supported payment methods
|
|
718
|
+
*
|
|
719
|
+
* @param value - The value to check
|
|
720
|
+
* @returns True if the value is a valid PaymentMethod, narrowing the type
|
|
474
721
|
*/
|
|
475
722
|
function isPaymentMethod(value) {
|
|
476
723
|
return (typeof value === "string" &&
|
|
477
724
|
["credit_card", "debit_card", "bank_transfer", "digital_wallet"].includes(value));
|
|
478
725
|
}
|
|
726
|
+
// CURRENCY VALIDATION
|
|
727
|
+
// Summary: Type guard for currency validation
|
|
728
|
+
// Description: Checks if a value matches the allowed currency types
|
|
479
729
|
/**
|
|
480
730
|
* Type guard to check if a value is a valid Currency
|
|
731
|
+
*
|
|
732
|
+
* @summary Validates a value against supported currencies
|
|
733
|
+
* @description Checks if provided value is a string and matches one of the supported currencies (TRY, USD, EUR, GBP)
|
|
734
|
+
*
|
|
735
|
+
* @param value - The value to check
|
|
736
|
+
* @returns True if the value is a valid Currency, narrowing the type
|
|
481
737
|
*/
|
|
482
738
|
function isCurrency(value) {
|
|
483
739
|
return (typeof value === "string" && ["TRY", "USD", "EUR", "GBP"].includes(value));
|
|
484
740
|
}
|
|
741
|
+
// STRING VALIDATION
|
|
742
|
+
// Summary: Type guard for non-empty string validation
|
|
743
|
+
// Description: Checks if a value is a string and contains non-whitespace characters
|
|
485
744
|
/**
|
|
486
745
|
* Type guard to check if a value is a non-empty string
|
|
746
|
+
*
|
|
747
|
+
* @summary Validates a value is a non-empty string
|
|
748
|
+
* @description Checks if provided value is of string type and contains at least one non-whitespace character
|
|
749
|
+
*
|
|
750
|
+
* @param value - The value to check
|
|
751
|
+
* @returns True if the value is a non-empty string, narrowing the type
|
|
487
752
|
*/
|
|
488
753
|
function isNonEmptyString(value) {
|
|
489
754
|
return typeof value === "string" && value.trim().length > 0;
|
|
490
755
|
}
|
|
756
|
+
// NUMBER VALIDATION
|
|
757
|
+
// Summary: Type guard for positive number validation
|
|
758
|
+
// Description: Checks if a value is a number greater than zero
|
|
491
759
|
/**
|
|
492
760
|
* Type guard to check if a value is a positive number
|
|
761
|
+
*
|
|
762
|
+
* @summary Validates a value is a positive number
|
|
763
|
+
* @description Checks if provided value is of number type, is greater than zero, and is not NaN or infinity
|
|
764
|
+
*
|
|
765
|
+
* @param value - The value to check
|
|
766
|
+
* @returns True if the value is a positive number, narrowing the type
|
|
493
767
|
*/
|
|
494
768
|
function isPositiveNumber(value) {
|
|
495
769
|
return (typeof value === "number" && value > 0 && !isNaN(value) && isFinite(value));
|
|
496
770
|
}
|
|
771
|
+
// INTEGER VALIDATION
|
|
772
|
+
// Summary: Type guard for integer validation
|
|
773
|
+
// Description: Checks if a value is an integer number
|
|
774
|
+
/**
|
|
775
|
+
* Type guard to check if a value is an integer
|
|
776
|
+
*
|
|
777
|
+
* @summary Validates a value is an integer
|
|
778
|
+
* @description Checks if provided value is of number type and is an integer (no decimal places)
|
|
779
|
+
*
|
|
780
|
+
* @param value - The value to check
|
|
781
|
+
* @returns True if the value is an integer, narrowing the type
|
|
782
|
+
*/
|
|
783
|
+
function isInteger(value) {
|
|
784
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
785
|
+
}
|
|
786
|
+
// DECIMAL PLACES VALIDATION
|
|
787
|
+
// Summary: Validates that a number has maximum 2 decimal places
|
|
788
|
+
// Description: Ensures monetary values have appropriate precision for currency operations
|
|
497
789
|
/**
|
|
498
790
|
* Type guard to check if amount has max 2 decimal places
|
|
791
|
+
*
|
|
792
|
+
* @summary Validates that a number has maximum 2 decimal places
|
|
793
|
+
* @description Ensures monetary values have appropriate precision for currency operations
|
|
794
|
+
*
|
|
795
|
+
* @param amount - The numeric amount to validate
|
|
796
|
+
* @returns True if the amount has 2 or fewer decimal places
|
|
499
797
|
*/
|
|
500
798
|
function hasValidDecimalPlaces(amount) {
|
|
501
799
|
const decimalPlaces = (amount.toString().split(".")[1] || "").length;
|
|
502
800
|
return decimalPlaces <= 2;
|
|
503
801
|
}
|
|
504
|
-
//
|
|
802
|
+
// VALIDATION FUNCTIONS
|
|
803
|
+
// BEARER TOKEN VALIDATION
|
|
804
|
+
// Summary: Validates authentication token format and security
|
|
805
|
+
// Description: Checks token for required length, character set, and format constraints
|
|
505
806
|
/**
|
|
506
807
|
* Validates Bearer token format and strength
|
|
507
808
|
*
|
|
809
|
+
* @summary Validates authentication token format and security
|
|
810
|
+
* @description Checks token for required length, character set, and format constraints
|
|
811
|
+
*
|
|
508
812
|
* @param bearerToken - Bearer token to validate
|
|
509
813
|
* @throws {TapsilatValidationError} When Bearer token is invalid
|
|
510
814
|
*/
|
|
@@ -515,14 +819,19 @@ function validateBearerToken(bearerToken) {
|
|
|
515
819
|
if (bearerToken.length < 10) {
|
|
516
820
|
throw new TapsilatValidationError("Bearer token must be at least 10 characters long");
|
|
517
821
|
}
|
|
518
|
-
// Karakter kontrolü (opsiyonel, isterseniz ek kurallar koyabilirsiniz)
|
|
519
822
|
if (!/^[a-zA-Z0-9._-]+$/.test(bearerToken)) {
|
|
520
823
|
throw new TapsilatValidationError("Bearer token contains invalid characters");
|
|
521
824
|
}
|
|
522
825
|
}
|
|
826
|
+
// PAYMENT REQUEST VALIDATION
|
|
827
|
+
// Summary: Comprehensive validation of payment request data
|
|
828
|
+
// Description: Validates all required and optional fields in a payment request for integrity and correctness
|
|
523
829
|
/**
|
|
524
830
|
* Validates payment request data comprehensively
|
|
525
831
|
*
|
|
832
|
+
* @summary Comprehensive validation of payment request data
|
|
833
|
+
* @description Validates all required and optional fields in a payment request for integrity and correctness
|
|
834
|
+
*
|
|
526
835
|
* @param request - Payment request to validate
|
|
527
836
|
* @throws {TapsilatValidationError} When any field is invalid
|
|
528
837
|
*/
|
|
@@ -566,9 +875,15 @@ function validatePaymentRequest(request) {
|
|
|
566
875
|
throw new TapsilatValidationError("Metadata must be an object when provided");
|
|
567
876
|
}
|
|
568
877
|
}
|
|
878
|
+
// EMAIL FORMAT VALIDATION
|
|
879
|
+
// Summary: Validates email address format with comprehensive regex
|
|
880
|
+
// Description: Ensures email addresses conform to RFC standards with thorough pattern matching
|
|
569
881
|
/**
|
|
570
882
|
* Validates email format using robust regex
|
|
571
883
|
*
|
|
884
|
+
* @summary Validates email address format with comprehensive regex
|
|
885
|
+
* @description Ensures email addresses conform to RFC standards with thorough pattern matching
|
|
886
|
+
*
|
|
572
887
|
* @param email - Email address to validate
|
|
573
888
|
* @returns True if email format is valid
|
|
574
889
|
*/
|
|
@@ -580,21 +895,45 @@ function validateEmail(email) {
|
|
|
580
895
|
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
581
896
|
return emailRegex.test(email);
|
|
582
897
|
}
|
|
898
|
+
// DEPRECATED CURRENCY VALIDATION
|
|
899
|
+
// Summary: Legacy currency validation function
|
|
900
|
+
// Description: Maintained for backwards compatibility, redirects to the new type guard
|
|
583
901
|
/**
|
|
584
902
|
* @deprecated Use isCurrency type guard instead
|
|
903
|
+
*
|
|
904
|
+
* @summary Legacy currency validation function
|
|
905
|
+
* @description Maintained for backwards compatibility, redirects to the new type guard
|
|
906
|
+
*
|
|
907
|
+
* @param currency - Currency code to validate
|
|
908
|
+
* @returns True if currency is supported
|
|
585
909
|
*/
|
|
586
910
|
function isValidCurrency(currency) {
|
|
587
911
|
return isCurrency(currency);
|
|
588
912
|
}
|
|
913
|
+
// DEPRECATED PAYMENT METHOD VALIDATION
|
|
914
|
+
// Summary: Legacy payment method validation function
|
|
915
|
+
// Description: Maintained for backwards compatibility, redirects to the new type guard
|
|
589
916
|
/**
|
|
590
917
|
* @deprecated Use isPaymentMethod type guard instead
|
|
918
|
+
*
|
|
919
|
+
* @summary Legacy payment method validation function
|
|
920
|
+
* @description Maintained for backwards compatibility, redirects to the new type guard
|
|
921
|
+
*
|
|
922
|
+
* @param paymentMethod - Payment method to validate
|
|
923
|
+
* @returns True if payment method is supported
|
|
591
924
|
*/
|
|
592
925
|
function isValidPaymentMethod(paymentMethod) {
|
|
593
926
|
return isPaymentMethod(paymentMethod);
|
|
594
927
|
}
|
|
928
|
+
// URL FORMAT VALIDATION
|
|
929
|
+
// Summary: Validates URL format and ensures proper protocol
|
|
930
|
+
// Description: Checks that URLs are well-formed and use HTTP or HTTPS protocols for security
|
|
595
931
|
/**
|
|
596
932
|
* Validates URL format and protocol
|
|
597
933
|
*
|
|
934
|
+
* @summary Validates URL format and ensures proper protocol
|
|
935
|
+
* @description Checks that URLs are well-formed and use HTTP or HTTPS protocols for security
|
|
936
|
+
*
|
|
598
937
|
* @param url - URL to validate
|
|
599
938
|
* @returns True if URL is valid HTTP/HTTPS
|
|
600
939
|
*/
|
|
@@ -610,9 +949,15 @@ function isValidUrl(url) {
|
|
|
610
949
|
return false;
|
|
611
950
|
}
|
|
612
951
|
}
|
|
952
|
+
// METADATA SANITIZATION
|
|
953
|
+
// Summary: Removes sensitive data from metadata before processing
|
|
954
|
+
// Description: Filters out security-sensitive keys and normalizes values for safe transmission
|
|
613
955
|
/**
|
|
614
956
|
* Sanitizes metadata by removing sensitive keys and cleaning values
|
|
615
957
|
*
|
|
958
|
+
* @summary Removes sensitive data from metadata before processing
|
|
959
|
+
* @description Filters out security-sensitive keys and normalizes values for safe transmission
|
|
960
|
+
*
|
|
616
961
|
* @param metadata - Raw metadata object
|
|
617
962
|
* @returns Sanitized metadata object
|
|
618
963
|
*/
|
|
@@ -657,93 +1002,307 @@ function sanitizeMetadata(metadata) {
|
|
|
657
1002
|
return sanitized;
|
|
658
1003
|
}
|
|
659
1004
|
|
|
1005
|
+
/**
|
|
1006
|
+
* @category Configuration
|
|
1007
|
+
* @summary Configuration management for Tapsilat SDK
|
|
1008
|
+
* @description Handles SDK configuration updates, validation, and secure access to configuration data
|
|
1009
|
+
* @class ConfigManager
|
|
1010
|
+
*/
|
|
1011
|
+
class ConfigManager {
|
|
1012
|
+
config;
|
|
1013
|
+
/**
|
|
1014
|
+
* @summary Creates a new configuration manager
|
|
1015
|
+
* @description Initializes the configuration manager with the provided configuration options
|
|
1016
|
+
*
|
|
1017
|
+
* @param config - Initial SDK configuration
|
|
1018
|
+
*/
|
|
1019
|
+
constructor(config) {
|
|
1020
|
+
this.config = { ...config }; // Create a copy to avoid external mutations
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* @category Configuration Access
|
|
1024
|
+
* @summary Get current SDK configuration without sensitive information
|
|
1025
|
+
* @description Returns a copy of the current configuration with sensitive data (like bearer token) excluded
|
|
1026
|
+
*
|
|
1027
|
+
* @returns Copy of current configuration without bearer token
|
|
1028
|
+
*/
|
|
1029
|
+
getConfig() {
|
|
1030
|
+
const { bearerToken, ...safeConfig } = this.config;
|
|
1031
|
+
return {
|
|
1032
|
+
...safeConfig,
|
|
1033
|
+
hasBearerToken: Boolean(bearerToken),
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* @category Configuration Management
|
|
1038
|
+
* @summary Update SDK configuration with new values
|
|
1039
|
+
* @description Updates the SDK configuration with provided values, validating bearer token if changed
|
|
1040
|
+
*
|
|
1041
|
+
* @param newConfig - Partial configuration to update
|
|
1042
|
+
* @throws {TapsilatValidationError} When Bearer token is invalid
|
|
1043
|
+
*/
|
|
1044
|
+
updateConfig(newConfig) {
|
|
1045
|
+
if (newConfig.bearerToken) {
|
|
1046
|
+
validateBearerToken(newConfig.bearerToken);
|
|
1047
|
+
}
|
|
1048
|
+
Object.assign(this.config, newConfig);
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* @category Internal
|
|
1052
|
+
* @summary Gets the internal configuration for SDK use
|
|
1053
|
+
* @description Returns a full copy of the configuration for internal SDK operations
|
|
1054
|
+
*
|
|
1055
|
+
* @internal
|
|
1056
|
+
* @returns Full configuration including sensitive data
|
|
1057
|
+
*/
|
|
1058
|
+
getInternalConfig() {
|
|
1059
|
+
return { ...this.config }; // Return a copy to prevent external mutations
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* @category Authentication
|
|
1063
|
+
* @summary Gets the bearer token for authentication
|
|
1064
|
+
* @description Retrieves the configured bearer token for API authentication
|
|
1065
|
+
*
|
|
1066
|
+
* @internal
|
|
1067
|
+
* @returns Bearer token
|
|
1068
|
+
*/
|
|
1069
|
+
getBearerToken() {
|
|
1070
|
+
return this.config.bearerToken;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* @category Endpoints
|
|
1074
|
+
* @summary Gets the base URL for API requests
|
|
1075
|
+
* @description Retrieves the configured base URL for API endpoints
|
|
1076
|
+
*
|
|
1077
|
+
* @internal
|
|
1078
|
+
* @returns API base URL
|
|
1079
|
+
*/
|
|
1080
|
+
getBaseUrl() {
|
|
1081
|
+
return this.config.baseURL;
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* @category Networking
|
|
1085
|
+
* @summary Gets the request timeout value
|
|
1086
|
+
* @description Retrieves the configured timeout value for API requests
|
|
1087
|
+
*
|
|
1088
|
+
* @internal
|
|
1089
|
+
* @returns Request timeout in milliseconds
|
|
1090
|
+
*/
|
|
1091
|
+
getTimeout() {
|
|
1092
|
+
return this.config.timeout;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// EMAIL VALIDATION
|
|
1097
|
+
// Summary: Validates email format using basic regex pattern
|
|
1098
|
+
// Description: Ensures email addresses conform to standard format with username, @ symbol, and domain
|
|
1099
|
+
/**
|
|
1100
|
+
* Validates email format using basic regex pattern
|
|
1101
|
+
*
|
|
1102
|
+
* @summary Validates email format using basic regex pattern
|
|
1103
|
+
* @description Ensures email addresses conform to standard format with username, @ symbol, and domain
|
|
1104
|
+
*
|
|
1105
|
+
* @param email - Email address to validate
|
|
1106
|
+
* @returns True if email matches required format, false otherwise
|
|
1107
|
+
*/
|
|
1108
|
+
const isValidEmail = (email) => {
|
|
1109
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1110
|
+
return emailRegex.test(email);
|
|
1111
|
+
};
|
|
1112
|
+
// API RESPONSE HANDLING
|
|
1113
|
+
// Summary: Process API responses consistently across the SDK
|
|
1114
|
+
// Description: Validates response structure, extracts data or converts API errors to domain errors
|
|
1115
|
+
/**
|
|
1116
|
+
* Generic response handler - consistent way to handle API responses
|
|
1117
|
+
*
|
|
1118
|
+
* @summary Process API responses consistently across the SDK
|
|
1119
|
+
* @description Validates response structure, extracts data or converts API errors to domain errors
|
|
1120
|
+
*
|
|
1121
|
+
* @param response - The API response to process
|
|
1122
|
+
* @param errorContext - Descriptive context for error messages
|
|
1123
|
+
* @returns The data from a successful response
|
|
1124
|
+
* @throws {TapsilatError} On any response error
|
|
1125
|
+
*/
|
|
1126
|
+
const handleResponse = (response, errorContext) => {
|
|
1127
|
+
if (!response.success || !response.data) {
|
|
1128
|
+
// Convert API errors to domain-specific errors
|
|
1129
|
+
if (response.error) {
|
|
1130
|
+
throw TapsilatError.fromAPIError(response.error);
|
|
1131
|
+
}
|
|
1132
|
+
throw new TapsilatError(`${errorContext} failed with no error details`, "UNKNOWN_ERROR");
|
|
1133
|
+
}
|
|
1134
|
+
return response.data;
|
|
1135
|
+
};
|
|
1136
|
+
// ERROR HANDLING
|
|
1137
|
+
// Summary: Centralized error handling for consistent error reporting
|
|
1138
|
+
// Description: Processes caught errors and ensures they are properly converted to TapsilatError types
|
|
1139
|
+
/**
|
|
1140
|
+
* Generic error handler - consistent way to handle errors
|
|
1141
|
+
*
|
|
1142
|
+
* @summary Centralized error handling for consistent error reporting
|
|
1143
|
+
* @description Processes caught errors and ensures they are properly converted to TapsilatError types
|
|
1144
|
+
*
|
|
1145
|
+
* @param error - The caught error to process
|
|
1146
|
+
* @param errorContext - Descriptive context for error messages
|
|
1147
|
+
* @throws {TapsilatError} Always throws an appropriate error type
|
|
1148
|
+
*/
|
|
1149
|
+
const handleError = (error, errorContext) => {
|
|
1150
|
+
// Rethrow TapsilatErrors as-is
|
|
1151
|
+
if (error instanceof TapsilatError) {
|
|
1152
|
+
throw error;
|
|
1153
|
+
}
|
|
1154
|
+
// Convert generic errors to TapsilatNetworkError
|
|
1155
|
+
throw new TapsilatNetworkError(error instanceof Error
|
|
1156
|
+
? error.message
|
|
1157
|
+
: `Unknown error during ${errorContext}`, "NETWORK_ERROR");
|
|
1158
|
+
};
|
|
1159
|
+
// WEBHOOK SIGNATURE VERIFICATION
|
|
1160
|
+
// Summary: Security verification of webhook payloads using HMAC-SHA256
|
|
1161
|
+
// Description: Computes expected signature from payload and secret, compares with provided signature
|
|
1162
|
+
/**
|
|
1163
|
+
* Verifies HMAC-SHA256 signature for webhook security
|
|
1164
|
+
*
|
|
1165
|
+
* @summary Security verification of webhook payloads using HMAC-SHA256
|
|
1166
|
+
* @description Computes expected signature from payload and secret, compares with provided signature
|
|
1167
|
+
*
|
|
1168
|
+
* @param payload - Raw webhook payload string
|
|
1169
|
+
* @param signature - Webhook signature from headers (should include "sha256=" prefix)
|
|
1170
|
+
* @param secret - Your webhook secret key
|
|
1171
|
+
* @returns true if signature is valid, false otherwise
|
|
1172
|
+
*/
|
|
1173
|
+
const verifyHmacSignature = (payload, signature, secret) => {
|
|
1174
|
+
const expectedSignature = crypto
|
|
1175
|
+
.createHmac("sha256", secret)
|
|
1176
|
+
.update(payload)
|
|
1177
|
+
.digest("hex");
|
|
1178
|
+
return `sha256=${expectedSignature}` === signature;
|
|
1179
|
+
};
|
|
1180
|
+
|
|
660
1181
|
/**
|
|
661
1182
|
* Main SDK class for Tapsilat payment operations
|
|
662
1183
|
*
|
|
663
|
-
* @
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
1184
|
+
* @summary Enterprise-grade TypeScript SDK for Tapsilat Payment Processing Platform
|
|
1185
|
+
* @description
|
|
1186
|
+
* The TapsilatSDK class provides a comprehensive interface for integrating with the Tapsilat payment platform.
|
|
1187
|
+
* It offers secure, efficient, and type-safe methods for managing orders, payments, refunds, and other
|
|
1188
|
+
* payment-related operations. The SDK includes built-in error handling, request validation, retry logic,
|
|
1189
|
+
* and comprehensive logging capabilities.
|
|
669
1190
|
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
1191
|
+
* Key features:
|
|
1192
|
+
* - Type-safe API with TypeScript support
|
|
1193
|
+
* - Built-in error handling with custom error types
|
|
1194
|
+
* - Automatic request/response validation
|
|
1195
|
+
* - Configurable retry mechanism
|
|
1196
|
+
* - Full compliance with Tapsilat API specifications
|
|
676
1197
|
*/
|
|
677
1198
|
class TapsilatSDK {
|
|
678
1199
|
httpClient;
|
|
679
|
-
|
|
1200
|
+
configManager;
|
|
1201
|
+
// SDK INITIALIZATION
|
|
1202
|
+
// Summary: Initializes the Tapsilat SDK with configuration options
|
|
1203
|
+
// Description: Creates and configures a new instance of the TapsilatSDK with the provided configuration
|
|
680
1204
|
/**
|
|
681
1205
|
* Creates a new TapsilatSDK instance
|
|
682
1206
|
*
|
|
683
|
-
* @
|
|
684
|
-
* @
|
|
1207
|
+
* @summary Initializes the Tapsilat SDK with configuration options
|
|
1208
|
+
* @description
|
|
1209
|
+
* Creates and configures a new instance of the TapsilatSDK with the provided configuration.
|
|
1210
|
+
* The constructor validates the bearer token, sets up the HTTP client with proper headers,
|
|
1211
|
+
* configures retry mechanisms, and initializes internal state for API communication.
|
|
1212
|
+
*
|
|
1213
|
+
* The SDK instance is immutable after creation - configuration cannot be changed without
|
|
1214
|
+
* creating a new instance. This ensures thread safety and predictable behavior.
|
|
1215
|
+
*
|
|
1216
|
+
* @param {TapsilatConfig} config - SDK configuration options
|
|
1217
|
+
* @param {string} config.bearerToken - API authentication token (required)
|
|
1218
|
+
* @param {string} [config.baseURL='https://api.tapsilat.com/v1'] - API base URL
|
|
1219
|
+
* @param {number} [config.timeout=30000] - Request timeout in milliseconds
|
|
1220
|
+
* @param {number} [config.maxRetries=3] - Maximum number of retry attempts
|
|
1221
|
+
* @param {number} [config.retryDelay=1000] - Delay between retries in milliseconds
|
|
1222
|
+
* @param {string} [config.version='v1'] - API version to use
|
|
1223
|
+
* @param {boolean} [config.debug=false] - Enable debug logging
|
|
1224
|
+
*
|
|
1225
|
+
* @throws {TapsilatValidationError} When bearer token is invalid, missing, or malformed
|
|
1226
|
+
* @throws {TypeError} When config parameter is not an object or missing required fields
|
|
685
1227
|
*/
|
|
686
1228
|
constructor(config) {
|
|
687
1229
|
validateBearerToken(config.bearerToken);
|
|
688
|
-
this.
|
|
689
|
-
this.httpClient = new HttpClient(
|
|
1230
|
+
this.configManager = new ConfigManager(config);
|
|
1231
|
+
this.httpClient = new HttpClient(this.configManager.getInternalConfig());
|
|
690
1232
|
}
|
|
691
|
-
//
|
|
1233
|
+
// ORDER CREATION
|
|
1234
|
+
// Summary: Create new payment order and get checkout URL
|
|
1235
|
+
// Description: Initiates payment process with buyer info and returns secure checkout URL
|
|
692
1236
|
/**
|
|
693
|
-
* Creates a new order and returns a checkout URL
|
|
1237
|
+
* Creates a new order and returns a checkout URL
|
|
694
1238
|
*
|
|
695
|
-
* @
|
|
696
|
-
* @
|
|
697
|
-
*
|
|
698
|
-
*
|
|
699
|
-
*
|
|
1239
|
+
* @summary Initiates a new payment order with buyer information and generates checkout URL
|
|
1240
|
+
* @description
|
|
1241
|
+
* Creates a new payment order in the Tapsilat system with the provided order details.
|
|
1242
|
+
* This method performs comprehensive validation of all input parameters, creates the order
|
|
1243
|
+
* on the payment platform, and returns a checkout URL that customers can use to complete
|
|
1244
|
+
* their payment. The method supports multiple currencies, locales, and comprehensive
|
|
1245
|
+
* buyer information for compliance and fraud prevention.
|
|
700
1246
|
*
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
* }
|
|
716
|
-
*
|
|
717
|
-
* }
|
|
718
|
-
*
|
|
1247
|
+
* The returned checkout URL is valid for a limited time (typically 24 hours) and should
|
|
1248
|
+
* be presented to the customer immediately. The order status can be tracked using the
|
|
1249
|
+
* returned reference ID through the getOrderStatus method.
|
|
1250
|
+
*
|
|
1251
|
+
* @param {OrderCreateRequest} orderRequest - Complete order information
|
|
1252
|
+
* @param {number} orderRequest.amount - Payment amount (must be positive, max 2 decimal places)
|
|
1253
|
+
* @param {Currency} orderRequest.currency - Payment currency ('TRY', 'USD', 'EUR', 'GBP')
|
|
1254
|
+
* @param {Locale} orderRequest.locale - Display language ('tr' for Turkish, 'en' for English)
|
|
1255
|
+
* @param {Buyer} orderRequest.buyer - Customer information for payment processing
|
|
1256
|
+
* @param {string} orderRequest.buyer.name - Customer's first name (required)
|
|
1257
|
+
* @param {string} orderRequest.buyer.surname - Customer's last name (required)
|
|
1258
|
+
* @param {string} orderRequest.buyer.email - Customer's email address (required, validated)
|
|
1259
|
+
* @param {string} [orderRequest.buyer.phone] - Customer's phone number
|
|
1260
|
+
* @param {string} [orderRequest.buyer.identityNumber] - National ID or tax number
|
|
1261
|
+
* @param {Address} [orderRequest.buyer.shippingAddress] - Shipping address for physical goods
|
|
1262
|
+
* @param {Address} [orderRequest.buyer.billingAddress] - Billing address for invoicing
|
|
1263
|
+
* @param {string} [orderRequest.description] - Order description for customer reference
|
|
1264
|
+
* @param {string} [orderRequest.callbackUrl] - URL to redirect after payment completion
|
|
1265
|
+
* @param {string} [orderRequest.conversationId] - Custom tracking ID for your system
|
|
1266
|
+
* @param {Record<string, unknown>} [orderRequest.metadata] - Additional custom data
|
|
1267
|
+
*
|
|
1268
|
+
* @returns {Promise<OrderCreateResponse>} Promise resolving to order creation response
|
|
1269
|
+
* @returns {string} OrderCreateResponse.referenceId - Unique order identifier for tracking
|
|
1270
|
+
* @returns {string} OrderCreateResponse.conversationId - Echo of provided conversation ID
|
|
1271
|
+
* @returns {string} OrderCreateResponse.checkoutUrl - Payment page URL for customer
|
|
1272
|
+
* @returns {string} OrderCreateResponse.status - Initial order status (typically 'CREATED')
|
|
1273
|
+
* @returns {string} [OrderCreateResponse.qrCodeUrl] - QR code URL for mobile payments
|
|
1274
|
+
*
|
|
1275
|
+
* @throws {TapsilatValidationError} When input validation fails:
|
|
1276
|
+
* - Amount is not positive or has more than 2 decimal places
|
|
1277
|
+
* - Currency is not supported
|
|
1278
|
+
* - Buyer information is incomplete or invalid
|
|
1279
|
+
* - Email format is invalid
|
|
1280
|
+
* - Required fields are missing
|
|
1281
|
+
* @throws {TapsilatNetworkError} When network request fails:
|
|
1282
|
+
* - Connection timeout
|
|
1283
|
+
* - DNS resolution failure
|
|
1284
|
+
* - Network connectivity issues
|
|
1285
|
+
* @throws {TapsilatError} When API returns business logic errors:
|
|
1286
|
+
* - Insufficient merchant balance
|
|
1287
|
+
* - Currency not enabled for merchant
|
|
1288
|
+
* - Buyer blocked due to fraud detection
|
|
1289
|
+
* - Rate limiting exceeded
|
|
719
1290
|
*/
|
|
720
1291
|
async createOrder(orderRequest) {
|
|
721
|
-
// Validate the order request
|
|
722
|
-
this.validateOrderRequest(orderRequest);
|
|
723
|
-
try {
|
|
724
|
-
// Make the API request
|
|
725
|
-
const response = await this.httpClient.post("/order/create", orderRequest);
|
|
726
|
-
// Use our generic response handler
|
|
727
|
-
return this.handleResponse(response, "Order creation");
|
|
728
|
-
}
|
|
729
|
-
catch (error) {
|
|
730
|
-
// Use our generic error handler
|
|
731
|
-
this.handleError(error, "order creation");
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Validates an order request object
|
|
736
|
-
* @private
|
|
737
|
-
*/
|
|
738
|
-
validateOrderRequest(orderRequest) {
|
|
1292
|
+
// Validate the order request directly
|
|
739
1293
|
// Check if request is null/undefined
|
|
740
1294
|
if (!orderRequest) {
|
|
741
1295
|
throw new TapsilatValidationError("Order request cannot be null or undefined");
|
|
742
1296
|
}
|
|
743
|
-
// Validate amount
|
|
744
|
-
if (!isPositiveNumber(orderRequest.amount)
|
|
745
|
-
|
|
746
|
-
|
|
1297
|
+
// Validate amount - check if positive
|
|
1298
|
+
if (!isPositiveNumber(orderRequest.amount)) {
|
|
1299
|
+
throw new TapsilatValidationError("Amount must be a positive number", {
|
|
1300
|
+
provided: orderRequest.amount,
|
|
1301
|
+
});
|
|
1302
|
+
}
|
|
1303
|
+
// Validate amount - check decimal places
|
|
1304
|
+
if (!hasValidDecimalPlaces(orderRequest.amount)) {
|
|
1305
|
+
throw new TapsilatValidationError("Amount must have maximum 2 decimal places", { provided: orderRequest.amount });
|
|
747
1306
|
}
|
|
748
1307
|
// Validate currency
|
|
749
1308
|
if (!isNonEmptyString(orderRequest.currency)) {
|
|
@@ -760,73 +1319,39 @@ class TapsilatSDK {
|
|
|
760
1319
|
if (!isNonEmptyString(buyer.surname)) {
|
|
761
1320
|
throw new TapsilatValidationError("Buyer surname is required and must be a non-empty string", { provided: buyer.surname });
|
|
762
1321
|
}
|
|
763
|
-
|
|
764
|
-
|
|
1322
|
+
// Validate buyer email - check if provided
|
|
1323
|
+
if (!isNonEmptyString(buyer.email)) {
|
|
1324
|
+
throw new TapsilatValidationError("Buyer email is required and must be a non-empty string", { provided: buyer.email });
|
|
765
1325
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
* @private
|
|
770
|
-
*/
|
|
771
|
-
isValidEmail(email) {
|
|
772
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
773
|
-
return emailRegex.test(email);
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Generic response handler - consistent way to handle API responses across SDK methods
|
|
777
|
-
* @private
|
|
778
|
-
*
|
|
779
|
-
* @param response - The API response to process
|
|
780
|
-
* @param errorContext - Descriptive context for error messages
|
|
781
|
-
* @returns The data from a successful response
|
|
782
|
-
* @throws {TapsilatError} On any response error
|
|
783
|
-
*/
|
|
784
|
-
handleResponse(response, errorContext) {
|
|
785
|
-
if (!response.success || !response.data) {
|
|
786
|
-
// Convert API errors to domain-specific errors
|
|
787
|
-
if (response.error) {
|
|
788
|
-
throw TapsilatError.fromAPIError(response.error);
|
|
789
|
-
}
|
|
790
|
-
throw new TapsilatError(`${errorContext} failed with no error details`, "UNKNOWN_ERROR");
|
|
1326
|
+
// Validate buyer email - check format
|
|
1327
|
+
if (!isValidEmail(buyer.email)) {
|
|
1328
|
+
throw new TapsilatValidationError("Buyer email must be a valid email address", { provided: buyer.email });
|
|
791
1329
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
*/
|
|
802
|
-
handleError(error, errorContext) {
|
|
803
|
-
// Rethrow TapsilatErrors as-is
|
|
804
|
-
if (error instanceof TapsilatError) {
|
|
805
|
-
throw error;
|
|
1330
|
+
try {
|
|
1331
|
+
// Make the API request
|
|
1332
|
+
const createOrderResponse = await this.httpClient.post("/order/create", orderRequest);
|
|
1333
|
+
// Use our generic response handler
|
|
1334
|
+
return handleResponse(createOrderResponse, "Order creation");
|
|
1335
|
+
}
|
|
1336
|
+
catch (error) {
|
|
1337
|
+
// Use our generic error handler
|
|
1338
|
+
return handleError(error, "order creation");
|
|
806
1339
|
}
|
|
807
|
-
// Convert generic errors to TapsilatNetworkError
|
|
808
|
-
throw new TapsilatNetworkError(error instanceof Error
|
|
809
|
-
? error.message
|
|
810
|
-
: `Unknown error during ${errorContext}`, "NETWORK_ERROR");
|
|
811
1340
|
}
|
|
1341
|
+
// ORDER RETRIEVAL BY REFERENCE ID
|
|
1342
|
+
// Summary: Get complete order details and information
|
|
1343
|
+
// Description: Retrieves full order data including buyer info, amounts, and current status
|
|
812
1344
|
/**
|
|
813
1345
|
* Gets an order by reference ID.
|
|
814
1346
|
*
|
|
1347
|
+
* @summary Retrieve complete order details and information
|
|
1348
|
+
* @description Gets complete order data including buyer info, amounts, and current status using the unique reference ID.
|
|
1349
|
+
*
|
|
815
1350
|
* @param referenceId - The unique reference ID of the order
|
|
816
1351
|
* @returns Promise resolving to the complete order details
|
|
817
1352
|
* @throws {TapsilatValidationError} When referenceId is invalid
|
|
818
1353
|
* @throws {TapsilatNetworkError} When API request fails due to network issues
|
|
819
1354
|
* @throws {TapsilatError} When API returns an error response
|
|
820
|
-
*
|
|
821
|
-
* @example
|
|
822
|
-
* ```typescript
|
|
823
|
-
* try {
|
|
824
|
-
* const order = await tapsilat.getOrder("ord_123456789");
|
|
825
|
-
* console.log(`Order amount: ${order.amount} ${order.currency}`);
|
|
826
|
-
* } catch (error) {
|
|
827
|
-
* console.error(`Failed to get order: ${error.message}`);
|
|
828
|
-
* }
|
|
829
|
-
* ```
|
|
830
1355
|
*/
|
|
831
1356
|
async getOrder(referenceId) {
|
|
832
1357
|
// Validate input
|
|
@@ -835,95 +1360,137 @@ class TapsilatSDK {
|
|
|
835
1360
|
}
|
|
836
1361
|
try {
|
|
837
1362
|
// Make the API request
|
|
838
|
-
const
|
|
1363
|
+
const getOrderResponse = await this.httpClient.get(`/order/${referenceId}`);
|
|
839
1364
|
// Use our generic response handler
|
|
840
|
-
return
|
|
1365
|
+
return handleResponse(getOrderResponse, "Order retrieval");
|
|
841
1366
|
}
|
|
842
1367
|
catch (error) {
|
|
843
1368
|
// Use our generic error handler
|
|
844
|
-
|
|
1369
|
+
return handleError(error, "order retrieval");
|
|
845
1370
|
}
|
|
846
1371
|
}
|
|
1372
|
+
// ORDER LISTING WITH PAGINATION
|
|
1373
|
+
// Summary: Retrieve paginated list of merchant orders
|
|
1374
|
+
// Description: Gets orders with pagination support, filtering, and sorting options
|
|
847
1375
|
/**
|
|
848
1376
|
* Lists orders with pagination support.
|
|
849
1377
|
*
|
|
1378
|
+
* @summary Retrieve paginated list of merchant orders
|
|
1379
|
+
* @description Gets orders with pagination support, filtering, and sorting options.
|
|
1380
|
+
*
|
|
850
1381
|
* @param params - Optional pagination parameters (page number and items per page)
|
|
851
1382
|
* @returns Promise resolving to paginated list of orders
|
|
852
1383
|
* @throws {TapsilatNetworkError} When API request fails due to network issues
|
|
853
1384
|
* @throws {TapsilatError} When API returns an error response
|
|
854
|
-
*
|
|
855
|
-
* @example
|
|
856
|
-
* ```typescript
|
|
857
|
-
* try {
|
|
858
|
-
* // Get the second page with 20 items per page
|
|
859
|
-
* const orderList = await tapsilat.getOrders({ page: 2, per_page: 20 });
|
|
860
|
-
* console.log(`Total orders: ${orderList.total}`);
|
|
861
|
-
* orderList.rows.forEach(order => {
|
|
862
|
-
* console.log(`Order ${order.referenceId}: ${order.amount} ${order.currency}`);
|
|
863
|
-
* });
|
|
864
|
-
* } catch (error) {
|
|
865
|
-
* console.error(`Failed to list orders: ${error.message}`);
|
|
866
|
-
* }
|
|
867
|
-
* ```
|
|
868
1385
|
*/
|
|
869
1386
|
async getOrders(params = {}) {
|
|
870
1387
|
try {
|
|
871
1388
|
// Validate pagination parameters if provided
|
|
872
|
-
if
|
|
873
|
-
|
|
874
|
-
|
|
1389
|
+
// Check if page is defined
|
|
1390
|
+
if (params.page !== undefined) {
|
|
1391
|
+
// Check if page is integer
|
|
1392
|
+
if (!isInteger(params.page)) {
|
|
1393
|
+
throw new TapsilatValidationError("Page number must be an integer", {
|
|
1394
|
+
provided: params.page,
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
// Check if page is positive
|
|
1398
|
+
if (params.page < 1) {
|
|
1399
|
+
throw new TapsilatValidationError("Page number must be greater than 0", { provided: params.page });
|
|
1400
|
+
}
|
|
875
1401
|
}
|
|
876
|
-
if
|
|
877
|
-
|
|
878
|
-
|
|
1402
|
+
// Check if per_page is defined
|
|
1403
|
+
if (params.per_page !== undefined) {
|
|
1404
|
+
// Check if per_page is integer
|
|
1405
|
+
if (!isInteger(params.per_page)) {
|
|
1406
|
+
throw new TapsilatValidationError("Items per page must be an integer", { provided: params.per_page });
|
|
1407
|
+
}
|
|
1408
|
+
// Check if per_page is positive
|
|
1409
|
+
if (params.per_page < 1) {
|
|
1410
|
+
throw new TapsilatValidationError("Items per page must be greater than 0", { provided: params.per_page });
|
|
1411
|
+
}
|
|
879
1412
|
}
|
|
880
1413
|
// Make the API request
|
|
881
|
-
const
|
|
1414
|
+
const getOrdersResponse = await this.httpClient.get("/order/list", { params: params });
|
|
882
1415
|
// Use our generic response handler
|
|
883
|
-
return
|
|
1416
|
+
return handleResponse(getOrdersResponse, "Order listing");
|
|
884
1417
|
}
|
|
885
1418
|
catch (error) {
|
|
886
1419
|
// Use our generic error handler
|
|
887
|
-
|
|
1420
|
+
return handleError(error, "order listing");
|
|
888
1421
|
}
|
|
889
1422
|
}
|
|
1423
|
+
// ORDER CANCELLATION
|
|
1424
|
+
// Summary: Cancel a pending order before payment completion
|
|
1425
|
+
// Description: Cancels unpaid order and prevents further payment processing
|
|
890
1426
|
/**
|
|
891
1427
|
* Cancels an order by reference_id.
|
|
1428
|
+
*
|
|
1429
|
+
* @summary Cancel a pending order before payment completion
|
|
1430
|
+
* @description Cancels unpaid order and prevents further payment processing.
|
|
1431
|
+
*
|
|
1432
|
+
* @param referenceId - The unique reference ID of the order to cancel
|
|
1433
|
+
* @returns Promise resolving to the canceled order details
|
|
1434
|
+
* @throws {TapsilatValidationError} When referenceId is invalid
|
|
1435
|
+
* @throws {TapsilatError} When API returns an error response or order cannot be canceled
|
|
892
1436
|
*/
|
|
893
1437
|
async cancelOrder(referenceId) {
|
|
894
|
-
|
|
895
|
-
|
|
1438
|
+
// Validate referenceId
|
|
1439
|
+
if (!isNonEmptyString(referenceId)) {
|
|
1440
|
+
throw new TapsilatValidationError("Order referenceId is required and must be a non-empty string", { provided: referenceId });
|
|
896
1441
|
}
|
|
897
|
-
const
|
|
1442
|
+
const cancelOrderResponse = await this.httpClient.post("/order/cancel", {
|
|
898
1443
|
reference_id: referenceId,
|
|
899
1444
|
});
|
|
900
|
-
if
|
|
901
|
-
|
|
1445
|
+
// Check if API call was successful
|
|
1446
|
+
if (!cancelOrderResponse.success) {
|
|
1447
|
+
throw new TapsilatError(cancelOrderResponse.error?.message ||
|
|
1448
|
+
"Order cancellation API call failed", cancelOrderResponse.error?.code || "CANCELLATION_API_FAILED");
|
|
1449
|
+
}
|
|
1450
|
+
// Check if response data exists
|
|
1451
|
+
if (!cancelOrderResponse.data) {
|
|
1452
|
+
throw new TapsilatError("Order cancellation response data is missing", "CANCELLATION_DATA_MISSING");
|
|
902
1453
|
}
|
|
903
|
-
return
|
|
1454
|
+
return cancelOrderResponse.data;
|
|
904
1455
|
}
|
|
1456
|
+
// ORDER STATUS RETRIEVAL
|
|
1457
|
+
// Summary: Retrieves real-time payment status and tracking information for a specific order
|
|
1458
|
+
// Description: Queries the payment platform to retrieve current status of an order using its reference ID
|
|
905
1459
|
/**
|
|
906
|
-
* Gets the status of an order by reference ID
|
|
1460
|
+
* Gets the current status of an order by reference ID
|
|
907
1461
|
*
|
|
908
|
-
* @
|
|
909
|
-
* @
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
*
|
|
1462
|
+
* @summary Retrieves real-time payment status and tracking information for a specific order
|
|
1463
|
+
* @description
|
|
1464
|
+
* Queries the Tapsilat payment platform to retrieve the current status of an order using its
|
|
1465
|
+
* unique reference ID. This method provides real-time information about payment progress,
|
|
1466
|
+
* completion status, and last update timestamp. It's essential for tracking payment flow
|
|
1467
|
+
* and implementing proper order state management in your application.
|
|
913
1468
|
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
918
|
-
*
|
|
919
|
-
*
|
|
920
|
-
*
|
|
921
|
-
*
|
|
922
|
-
*
|
|
923
|
-
*
|
|
924
|
-
*
|
|
925
|
-
* }
|
|
926
|
-
*
|
|
1469
|
+
* The status information includes payment state (CREATED, PENDING_PAYMENT, COMPLETED, CANCELLED),
|
|
1470
|
+
* last update timestamp, and any relevant status metadata. This method should be used to:
|
|
1471
|
+
* - Check if a payment has been completed after redirecting from checkout
|
|
1472
|
+
* - Monitor payment status for pending transactions
|
|
1473
|
+
* - Verify order state before fulfilling goods/services
|
|
1474
|
+
* - Implement webhook verification and status synchronization
|
|
1475
|
+
*
|
|
1476
|
+
* @param {string} referenceId - Unique order reference identifier from order creation
|
|
1477
|
+
*
|
|
1478
|
+
* @returns {Promise<OrderStatusResponse>} Promise resolving to current order status information
|
|
1479
|
+
* @returns {string} OrderStatusResponse.referenceId - Echo of the provided reference ID
|
|
1480
|
+
* @returns {string} OrderStatusResponse.status - Current payment status (CREATED, PENDING_PAYMENT, COMPLETED, CANCELLED, FAILED)
|
|
1481
|
+
* @returns {string} OrderStatusResponse.lastUpdatedAt - ISO 8601 timestamp of last status change
|
|
1482
|
+
*
|
|
1483
|
+
* @throws {TapsilatValidationError} When input validation fails:
|
|
1484
|
+
* - Reference ID is null, undefined, or empty string
|
|
1485
|
+
* - Reference ID format is invalid (should match order ID pattern)
|
|
1486
|
+
* @throws {TapsilatNetworkError} When network request fails:
|
|
1487
|
+
* - Connection timeout during status check
|
|
1488
|
+
* - DNS resolution failure
|
|
1489
|
+
* - Network connectivity issues
|
|
1490
|
+
* @throws {TapsilatError} When API returns business logic errors:
|
|
1491
|
+
* - ORDER_NOT_FOUND: Order with given reference ID doesn't exist
|
|
1492
|
+
* - ACCESS_DENIED: Order belongs to different merchant
|
|
1493
|
+
* - RATE_LIMIT_EXCEEDED: Too many status check requests
|
|
927
1494
|
*/
|
|
928
1495
|
async getOrderStatus(referenceId) {
|
|
929
1496
|
// Validate input using proper validation
|
|
@@ -932,187 +1499,274 @@ class TapsilatSDK {
|
|
|
932
1499
|
}
|
|
933
1500
|
try {
|
|
934
1501
|
// Make the API request
|
|
935
|
-
const
|
|
1502
|
+
const getOrderStatusResponse = await this.httpClient.get(`/order/${referenceId}/status`);
|
|
936
1503
|
// Use our generic response handler
|
|
937
|
-
return
|
|
1504
|
+
return handleResponse(getOrderStatusResponse, "Order status retrieval");
|
|
938
1505
|
}
|
|
939
1506
|
catch (error) {
|
|
940
1507
|
// Use our generic error handler
|
|
941
|
-
|
|
1508
|
+
return handleError(error, "order status retrieval");
|
|
942
1509
|
}
|
|
943
1510
|
}
|
|
1511
|
+
// ORDER REFUND OPERATIONS
|
|
1512
|
+
// Summary: Process partial refund for a completed order
|
|
1513
|
+
// Description: Refunds specified amount from a paid order and returns transaction details
|
|
944
1514
|
/**
|
|
945
1515
|
* Partially refunds an order.
|
|
946
1516
|
* Based on `refund_order` from the Python SDK.
|
|
947
1517
|
*
|
|
1518
|
+
* @summary Process partial refund for a completed order
|
|
1519
|
+
* @description Refunds specified amount from a paid order and returns transaction details.
|
|
1520
|
+
*
|
|
948
1521
|
* @param refundData - The refund details, including referenceId and amount.
|
|
949
1522
|
* @returns Promise resolving to the refund transaction details.
|
|
1523
|
+
* @throws {TapsilatError} When API returns an error response or refund fails
|
|
950
1524
|
*/
|
|
951
1525
|
async refundOrder(refundData) {
|
|
952
|
-
const
|
|
953
|
-
if (!
|
|
954
|
-
throw new
|
|
1526
|
+
const refundOrderResponse = await this.httpClient.post("/order/refund", refundData);
|
|
1527
|
+
if (!refundOrderResponse.success) {
|
|
1528
|
+
throw new TapsilatError(refundOrderResponse.error?.message || "Order refund failed", refundOrderResponse.error?.code || "REFUND_FAILED");
|
|
955
1529
|
}
|
|
956
|
-
|
|
1530
|
+
if (!refundOrderResponse.data) {
|
|
1531
|
+
throw new TapsilatError("Order refund response data is missing", "REFUND_DATA_MISSING");
|
|
1532
|
+
}
|
|
1533
|
+
return refundOrderResponse.data;
|
|
957
1534
|
}
|
|
1535
|
+
// ORDER FULL REFUND OPERATIONS
|
|
1536
|
+
// Summary: Process full refund for a completed order
|
|
1537
|
+
// Description: Refunds entire order amount and returns transaction details
|
|
958
1538
|
/**
|
|
959
1539
|
* Fully refunds an order by its reference ID.
|
|
960
1540
|
* Based on `refund_all_order` from the Python SDK.
|
|
961
1541
|
*
|
|
1542
|
+
* @summary Process full refund for a completed order
|
|
1543
|
+
* @description Refunds entire order amount and returns transaction details.
|
|
1544
|
+
*
|
|
962
1545
|
* @param referenceId - The unique identifier of the order to fully refund.
|
|
963
1546
|
* @returns Promise resolving to the refund transaction details.
|
|
1547
|
+
* @throws {TapsilatError} When API returns an error response or full refund fails
|
|
964
1548
|
*/
|
|
965
1549
|
async refundAllOrder(referenceId) {
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
|
|
1550
|
+
const refundAllOrderResponse = await this.httpClient.post("/order/refund-all", {
|
|
1551
|
+
reference_id: referenceId,
|
|
1552
|
+
});
|
|
1553
|
+
if (!refundAllOrderResponse.success) {
|
|
1554
|
+
throw new TapsilatError(refundAllOrderResponse.error?.message || "Full order refund failed", refundAllOrderResponse.error?.code || "FULL_REFUND_FAILED");
|
|
1555
|
+
}
|
|
1556
|
+
if (!refundAllOrderResponse.data) {
|
|
1557
|
+
throw new TapsilatError("Full order refund response data is missing", "FULL_REFUND_DATA_MISSING");
|
|
969
1558
|
}
|
|
970
|
-
return
|
|
1559
|
+
return refundAllOrderResponse.data;
|
|
971
1560
|
}
|
|
1561
|
+
// ORDER PAYMENT DETAILS
|
|
1562
|
+
// Summary: Retrieve detailed payment transaction information for an order
|
|
1563
|
+
// Description: Gets payment method, amount, status, and card info for order transactions
|
|
972
1564
|
/**
|
|
973
1565
|
* Retrieves the payment details for an order.
|
|
974
1566
|
* Based on `get_order_payment_details` from the Python SDK.
|
|
975
1567
|
*
|
|
1568
|
+
* @summary Retrieve detailed payment transaction information for an order
|
|
1569
|
+
* @description Gets payment method, amount, status, and card info for order transactions.
|
|
1570
|
+
*
|
|
976
1571
|
* @param referenceId - The unique identifier of the order.
|
|
977
1572
|
* @param conversationId - Optional conversation ID for more specific querying.
|
|
978
1573
|
* @returns Promise resolving to a list of payment details.
|
|
1574
|
+
* @throws {TapsilatValidationError} When referenceId is invalid
|
|
1575
|
+
* @throws {TapsilatError} When API returns an error response or payment details are missing
|
|
979
1576
|
*/
|
|
980
1577
|
async getOrderPaymentDetails(referenceId, conversationId) {
|
|
981
|
-
if (
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1578
|
+
if (!isNonEmptyString(referenceId))
|
|
1579
|
+
throw new TapsilatValidationError("Reference ID is required and must be a non-empty string");
|
|
1580
|
+
const getOrderPaymentDetailsResponse = conversationId
|
|
1581
|
+
? await this.httpClient.post("/order/payment-details", {
|
|
1582
|
+
conversation_id: conversationId,
|
|
1583
|
+
})
|
|
1584
|
+
: await this.httpClient.get(`/order/${referenceId}/payment-details`);
|
|
1585
|
+
if (!getOrderPaymentDetailsResponse.success)
|
|
1586
|
+
throw new TapsilatError(getOrderPaymentDetailsResponse.error?.message ||
|
|
1587
|
+
"Payment details API call failed", getOrderPaymentDetailsResponse.error?.code ||
|
|
1588
|
+
"PAYMENT_DETAILS_API_FAILED");
|
|
1589
|
+
if (!getOrderPaymentDetailsResponse.data)
|
|
1590
|
+
throw new TapsilatError("Payment details response data is missing", "PAYMENT_DETAILS_DATA_MISSING");
|
|
1591
|
+
return getOrderPaymentDetailsResponse.data;
|
|
1592
|
+
}
|
|
1593
|
+
// ORDER LOOKUP BY CONVERSATION ID
|
|
1594
|
+
// Summary: Find order using conversation ID instead of reference ID
|
|
1595
|
+
// Description: Alternative lookup method for orders using custom conversation identifier
|
|
998
1596
|
/**
|
|
999
1597
|
* Gets an order by conversation_id.
|
|
1000
1598
|
* Based on `get_order_by_conversation_id` from the Python SDK.
|
|
1599
|
+
*
|
|
1600
|
+
* @summary Find order using conversation ID instead of reference ID
|
|
1601
|
+
* @description Alternative lookup method for orders using custom conversation identifier.
|
|
1602
|
+
*
|
|
1603
|
+
* @param conversationId - The custom conversation identifier used when creating the order
|
|
1604
|
+
* @returns Promise resolving to the complete order details
|
|
1605
|
+
* @throws {TapsilatValidationError} When conversationId is invalid
|
|
1606
|
+
* @throws {TapsilatError} When API returns an error response
|
|
1001
1607
|
*/
|
|
1002
1608
|
async getOrderByConversationId(conversationId) {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
const response = await this.httpClient.get(`/order/conversation/${conversationId}`);
|
|
1007
|
-
if (!response.success || !response.data) {
|
|
1008
|
-
throw new Error(response.error?.message || "Order retrieval by conversation ID failed");
|
|
1609
|
+
// Validate conversationId
|
|
1610
|
+
if (!isNonEmptyString(conversationId)) {
|
|
1611
|
+
throw new TapsilatValidationError("Order conversationId is required and must be a non-empty string", { provided: conversationId });
|
|
1009
1612
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1613
|
+
const getOrderByConversationIdResponse = await this.httpClient.get(`/order/conversation/${conversationId}`);
|
|
1614
|
+
if (!getOrderByConversationIdResponse.success)
|
|
1615
|
+
throw new TapsilatError(getOrderByConversationIdResponse.error?.message ||
|
|
1616
|
+
"Order retrieval by conversation ID failed", getOrderByConversationIdResponse.error?.code || "ORDER_RETRIEVAL_FAILED");
|
|
1617
|
+
if (!getOrderByConversationIdResponse.data)
|
|
1618
|
+
throw new TapsilatError("Order response data is missing", "ORDER_DATA_MISSING");
|
|
1619
|
+
return getOrderByConversationIdResponse.data;
|
|
1620
|
+
}
|
|
1621
|
+
// ORDER TRANSACTION HISTORY
|
|
1622
|
+
// Summary: Retrieve transaction history for an order
|
|
1623
|
+
// Description: Gets detailed transaction records and payment attempts for a specific order
|
|
1012
1624
|
/**
|
|
1013
1625
|
* Gets order transactions by reference_id.
|
|
1014
1626
|
* Based on `get_order_transactions` from the Python SDK.
|
|
1627
|
+
*
|
|
1628
|
+
* @summary Retrieve transaction history for an order
|
|
1629
|
+
* @description Gets detailed transaction records and payment attempts for a specific order.
|
|
1630
|
+
*
|
|
1631
|
+
* @param referenceId - The unique reference ID of the order
|
|
1632
|
+
* @returns Promise resolving to array of transaction records
|
|
1633
|
+
* @throws {TapsilatValidationError} When referenceId is invalid
|
|
1634
|
+
* @throws {TapsilatError} When API returns an error response
|
|
1015
1635
|
*/
|
|
1016
1636
|
async getOrderTransactions(referenceId) {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
const response = await this.httpClient.get(`/order/${referenceId}/transactions`);
|
|
1021
|
-
if (!response.success || !response.data) {
|
|
1022
|
-
throw new Error(response.error?.message || "Order transactions retrieval failed");
|
|
1637
|
+
// Validate referenceId
|
|
1638
|
+
if (!isNonEmptyString(referenceId)) {
|
|
1639
|
+
throw new TapsilatValidationError("Order referenceId is required and must be a non-empty string", { provided: referenceId });
|
|
1023
1640
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1641
|
+
const getOrderTransactionsResponse = await this.httpClient.get(`/order/${referenceId}/transactions`);
|
|
1642
|
+
if (!getOrderTransactionsResponse.success)
|
|
1643
|
+
throw new TapsilatError(getOrderTransactionsResponse.error?.message ||
|
|
1644
|
+
"Order transactions retrieval failed", getOrderTransactionsResponse.error?.code ||
|
|
1645
|
+
"TRANSACTIONS_RETRIEVAL_FAILED");
|
|
1646
|
+
if (!getOrderTransactionsResponse.data)
|
|
1647
|
+
throw new TapsilatError("Order transactions response data is missing", "TRANSACTIONS_DATA_MISSING");
|
|
1648
|
+
return getOrderTransactionsResponse.data;
|
|
1649
|
+
}
|
|
1650
|
+
// ORDER SUBMERCHANT LISTING
|
|
1651
|
+
// Summary: Retrieve paginated list of submerchants for orders
|
|
1652
|
+
// Description: Gets submerchant information with pagination support for order management
|
|
1026
1653
|
/**
|
|
1027
1654
|
* Gets order submerchants with pagination.
|
|
1028
1655
|
* Based on `get_order_submerchants` from the Python SDK.
|
|
1656
|
+
*
|
|
1657
|
+
* @summary Retrieve paginated list of submerchants for orders
|
|
1658
|
+
* @description Gets submerchant information with pagination support for order management.
|
|
1659
|
+
*
|
|
1660
|
+
* @param params - Optional pagination parameters (page number and items per page)
|
|
1661
|
+
* @returns Promise resolving to paginated list of submerchants
|
|
1662
|
+
* @throws {TapsilatError} When API returns an error response
|
|
1029
1663
|
*/
|
|
1030
1664
|
async getOrderSubmerchants(params = {}) {
|
|
1031
|
-
const
|
|
1665
|
+
const getOrderSubmerchantsResponse = await this.httpClient.get("/order/submerchants", {
|
|
1032
1666
|
params: params,
|
|
1033
1667
|
});
|
|
1034
|
-
if (!
|
|
1035
|
-
throw new
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1668
|
+
if (!getOrderSubmerchantsResponse.success)
|
|
1669
|
+
throw new TapsilatError(getOrderSubmerchantsResponse.error?.message ||
|
|
1670
|
+
"Order submerchants retrieval failed", getOrderSubmerchantsResponse.error?.code ||
|
|
1671
|
+
"SUBMERCHANTS_RETRIEVAL_FAILED");
|
|
1672
|
+
if (!getOrderSubmerchantsResponse.data)
|
|
1673
|
+
throw new TapsilatError("Order submerchants response data is missing", "SUBMERCHANTS_DATA_MISSING");
|
|
1674
|
+
return getOrderSubmerchantsResponse.data;
|
|
1675
|
+
}
|
|
1676
|
+
// ORDER CHECKOUT URL RETRIEVAL
|
|
1677
|
+
// Summary: Retrieve checkout URL for existing order
|
|
1678
|
+
// Description: Gets the payment checkout URL for an existing order using reference ID
|
|
1039
1679
|
/**
|
|
1040
1680
|
* Gets checkout URL for an order.
|
|
1041
1681
|
* Based on `get_checkout_url` from the Python SDK.
|
|
1682
|
+
*
|
|
1683
|
+
* @summary Retrieve checkout URL for existing order
|
|
1684
|
+
* @description Gets the payment checkout URL for an existing order using reference ID.
|
|
1685
|
+
*
|
|
1686
|
+
* @param referenceId - The unique reference ID of the order
|
|
1687
|
+
* @returns Promise resolving to the checkout URL string
|
|
1688
|
+
* @throws {TapsilatError} When checkout URL is not found in order response
|
|
1042
1689
|
*/
|
|
1043
1690
|
async getCheckoutUrl(referenceId) {
|
|
1044
1691
|
const order = await this.getOrder(referenceId);
|
|
1045
1692
|
if (order && order.checkout_url) {
|
|
1046
1693
|
return order.checkout_url;
|
|
1047
1694
|
}
|
|
1048
|
-
throw new
|
|
1695
|
+
throw new TapsilatError("Checkout URL not found in order response", "CHECKOUT_URL_NOT_FOUND");
|
|
1049
1696
|
}
|
|
1050
|
-
//
|
|
1697
|
+
// WEBHOOK SIGNATURE VERIFICATION
|
|
1698
|
+
// Summary: Validate webhook signature for security verification
|
|
1699
|
+
// Description: Verifies the authenticity of webhook payloads using HMAC signature validation
|
|
1051
1700
|
/**
|
|
1052
1701
|
* Verifies webhook signature for security
|
|
1053
1702
|
*
|
|
1703
|
+
* @summary Validate webhook signature for security verification
|
|
1704
|
+
* @description Verifies the authenticity of webhook payloads using HMAC signature validation.
|
|
1705
|
+
*
|
|
1054
1706
|
* @param payload - Raw webhook payload string
|
|
1055
1707
|
* @param signature - Webhook signature from headers
|
|
1056
1708
|
* @param secret - Your webhook secret key
|
|
1057
1709
|
* @returns Promise resolving to true if signature is valid
|
|
1058
|
-
*
|
|
1059
|
-
* @example
|
|
1060
|
-
* ```typescript
|
|
1061
|
-
* const isValid = await sdk.verifyWebhook(
|
|
1062
|
-
* JSON.stringify(req.body),
|
|
1063
|
-
* req.headers['x-tapsilat-signature'],
|
|
1064
|
-
* 'your-webhook-secret'
|
|
1065
|
-
* );
|
|
1066
|
-
* ```
|
|
1710
|
+
* @throws {TapsilatValidationError} When input validation fails for payload, signature or secret
|
|
1067
1711
|
*/
|
|
1068
1712
|
async verifyWebhook(payload, signature, secret) {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1713
|
+
if (!isNonEmptyString(payload))
|
|
1714
|
+
throw new TapsilatValidationError("Webhook payload is required and must be a non-empty string");
|
|
1715
|
+
if (!isNonEmptyString(signature))
|
|
1716
|
+
throw new TapsilatValidationError("Webhook signature is required and must be a non-empty string");
|
|
1717
|
+
if (!isNonEmptyString(secret))
|
|
1718
|
+
throw new TapsilatValidationError("Webhook secret is required and must be a non-empty string");
|
|
1719
|
+
return verifyHmacSignature(payload, signature, secret);
|
|
1720
|
+
}
|
|
1721
|
+
// API HEALTH STATUS CHECK
|
|
1722
|
+
// Summary: Check API service health and availability
|
|
1723
|
+
// Description: Verifies that the Tapsilat API service is operational and accessible
|
|
1078
1724
|
/**
|
|
1079
1725
|
* Checks API service health and availability
|
|
1080
1726
|
*
|
|
1081
|
-
* @
|
|
1727
|
+
* @summary Check API service health and availability
|
|
1728
|
+
* @description Verifies that the Tapsilat API service is operational and accessible.
|
|
1729
|
+
*
|
|
1730
|
+
* @returns Promise resolving to service status with status string and timestamp
|
|
1731
|
+
* @throws {TapsilatError} When API health check fails or returns invalid data
|
|
1082
1732
|
*/
|
|
1083
1733
|
async healthCheck() {
|
|
1084
|
-
const
|
|
1085
|
-
if (!
|
|
1086
|
-
throw new
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1734
|
+
const healthCheckResponse = await this.httpClient.get("/health");
|
|
1735
|
+
if (!healthCheckResponse.success)
|
|
1736
|
+
throw new TapsilatError(healthCheckResponse.error?.message || "Health check failed", healthCheckResponse.error?.code || "HEALTH_CHECK_FAILED");
|
|
1737
|
+
if (!healthCheckResponse.data)
|
|
1738
|
+
throw new TapsilatError("Health check response data is missing", "HEALTH_CHECK_DATA_MISSING");
|
|
1739
|
+
return healthCheckResponse.data;
|
|
1740
|
+
}
|
|
1741
|
+
// CONFIGURATION MANAGEMENT
|
|
1742
|
+
// Summary: Access to the configuration manager for advanced configuration management
|
|
1743
|
+
// Description: Provides direct access to the ConfigManager instance for configuration operations
|
|
1091
1744
|
/**
|
|
1092
|
-
* Gets
|
|
1745
|
+
* Gets the configuration manager instance
|
|
1093
1746
|
*
|
|
1094
|
-
* @
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
return {
|
|
1099
|
-
...safeConfig,
|
|
1100
|
-
hasBearerToken: Boolean(bearerToken),
|
|
1101
|
-
};
|
|
1102
|
-
}
|
|
1103
|
-
/**
|
|
1104
|
-
* Updates SDK configuration
|
|
1747
|
+
* @summary Access to the configuration manager for advanced configuration management
|
|
1748
|
+
* @description
|
|
1749
|
+
* Provides direct access to the ConfigManager instance for configuration operations.
|
|
1750
|
+
* Use this to get, update, or manage SDK configuration settings.
|
|
1105
1751
|
*
|
|
1106
|
-
* @
|
|
1107
|
-
*
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```typescript
|
|
1754
|
+
* const sdk = new TapsilatSDK(config);
|
|
1755
|
+
* const configManager = sdk.getConfigManager();
|
|
1756
|
+
*
|
|
1757
|
+
* // Get config (without sensitive data)
|
|
1758
|
+
* console.log(configManager.getConfig());
|
|
1759
|
+
*
|
|
1760
|
+
* // Update config
|
|
1761
|
+
* configManager.updateConfig({ timeout: 60000 });
|
|
1762
|
+
* ```
|
|
1763
|
+
*
|
|
1764
|
+
* @returns ConfigManager instance for configuration operations
|
|
1108
1765
|
*/
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
validateBearerToken(newConfig.bearerToken);
|
|
1112
|
-
}
|
|
1113
|
-
Object.assign(this.config, newConfig);
|
|
1766
|
+
getConfigManager() {
|
|
1767
|
+
return this.configManager;
|
|
1114
1768
|
}
|
|
1115
1769
|
}
|
|
1116
1770
|
|
|
1117
|
-
export { TapsilatAuthenticationError, TapsilatError, TapsilatNetworkError, TapsilatRateLimitError, TapsilatSDK, TapsilatValidationError, isValidCurrency, isValidPaymentMethod, isValidUrl, sanitizeMetadata, validateEmail, validatePaymentRequest };
|
|
1771
|
+
export { ConfigManager, TapsilatAuthenticationError, TapsilatError, TapsilatNetworkError, TapsilatRateLimitError, TapsilatSDK, TapsilatValidationError, isValidCurrency, isValidPaymentMethod, isValidUrl, sanitizeMetadata, validateEmail, validatePaymentRequest };
|
|
1118
1772
|
//# sourceMappingURL=index.esm.js.map
|