@tapsilat/tapsilat-js 1.0.7 → 2025.11.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -0
- package/dist/TapsilatSDK.d.ts +148 -34
- package/dist/TapsilatSDK.d.ts.map +1 -1
- package/dist/__mocks__/HttpClient.d.ts +9 -0
- package/dist/__mocks__/HttpClient.d.ts.map +1 -0
- package/dist/http/HttpClient.d.ts.map +1 -1
- package/dist/index.d.ts +356 -51
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +486 -52
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +487 -51
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +169 -16
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/validators.d.ts +39 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/package.json +16 -17
package/dist/index.esm.js
CHANGED
|
@@ -258,7 +258,7 @@ class InterceptorManager {
|
|
|
258
258
|
try {
|
|
259
259
|
return await interceptor(error, request);
|
|
260
260
|
}
|
|
261
|
-
catch
|
|
261
|
+
catch {
|
|
262
262
|
// Continue to next interceptor if this one fails
|
|
263
263
|
continue;
|
|
264
264
|
}
|
|
@@ -365,15 +365,10 @@ class HttpClient {
|
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
// Execute error interceptors as last resort
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
catch (finalError) {
|
|
375
|
-
throw finalError;
|
|
376
|
-
}
|
|
368
|
+
return this.interceptors.executeErrorInterceptors(lastError, {
|
|
369
|
+
url: interceptedUrl,
|
|
370
|
+
options: interceptedOptions,
|
|
371
|
+
});
|
|
377
372
|
}
|
|
378
373
|
/**
|
|
379
374
|
* @category HTTP Client Internals
|
|
@@ -434,7 +429,7 @@ class HttpClient {
|
|
|
434
429
|
responseData = await response.text();
|
|
435
430
|
}
|
|
436
431
|
}
|
|
437
|
-
catch
|
|
432
|
+
catch {
|
|
438
433
|
throw new TapsilatError("Failed to parse response body", "PARSE_ERROR");
|
|
439
434
|
}
|
|
440
435
|
// Handle successful responses
|
|
@@ -476,11 +471,12 @@ class HttpClient {
|
|
|
476
471
|
return new TapsilatValidationError(errorMessage || "Invalid request data");
|
|
477
472
|
case 422:
|
|
478
473
|
return new TapsilatValidationError(errorMessage || "Validation failed", this.extractValidationDetails(data));
|
|
479
|
-
case 429:
|
|
474
|
+
case 429: {
|
|
480
475
|
const rateLimitInfo = this.extractRateLimitInfo(response);
|
|
481
476
|
return new TapsilatRateLimitError(errorMessage || "Rate limit exceeded", rateLimitInfo.resetTime
|
|
482
477
|
? Math.floor((rateLimitInfo.resetTime.getTime() - Date.now()) / 1000)
|
|
483
478
|
: undefined);
|
|
479
|
+
}
|
|
484
480
|
case 404:
|
|
485
481
|
return new TapsilatError(errorMessage || "Resource not found", "NOT_FOUND");
|
|
486
482
|
case 500:
|
|
@@ -1017,6 +1013,186 @@ function sanitizeMetadata(metadata) {
|
|
|
1017
1013
|
}
|
|
1018
1014
|
return sanitized;
|
|
1019
1015
|
}
|
|
1016
|
+
// GSM NUMBER VALIDATION
|
|
1017
|
+
// Summary: Validates and cleans Turkish GSM phone numbers
|
|
1018
|
+
// Description: Supports multiple phone number formats and automatically cleans formatting
|
|
1019
|
+
/**
|
|
1020
|
+
* Validates and cleans GSM phone numbers
|
|
1021
|
+
*
|
|
1022
|
+
* @summary Validates and cleans Turkish GSM phone numbers
|
|
1023
|
+
* @description
|
|
1024
|
+
* Supports multiple phone number formats including international (+90), national (0),
|
|
1025
|
+
* and local formats. Automatically removes formatting characters and validates
|
|
1026
|
+
* against Turkish mobile number patterns.
|
|
1027
|
+
*
|
|
1028
|
+
* Supported formats:
|
|
1029
|
+
* - +90 5XX XXX XX XX
|
|
1030
|
+
* - 0 5XX XXX XX XX
|
|
1031
|
+
* - 5XX XXX XX XX
|
|
1032
|
+
* - Various formatting with spaces, dashes, parentheses
|
|
1033
|
+
*
|
|
1034
|
+
* @param {string | number} gsmNumber - GSM number to validate and clean
|
|
1035
|
+
* @returns {GsmValidationResult} Validation result with cleaned number or error
|
|
1036
|
+
*/
|
|
1037
|
+
function validateGsmNumber(gsmNumber) {
|
|
1038
|
+
const originalNumber = String(gsmNumber);
|
|
1039
|
+
// Basic validation
|
|
1040
|
+
if (!originalNumber || typeof originalNumber !== 'string') {
|
|
1041
|
+
return {
|
|
1042
|
+
isValid: false,
|
|
1043
|
+
error: "GSM number must be a non-empty string",
|
|
1044
|
+
originalNumber
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
// Clean the number - remove all non-digit characters
|
|
1048
|
+
let cleanedNumber = originalNumber.replace(/[^\d]/g, '');
|
|
1049
|
+
// Handle different formats
|
|
1050
|
+
if (cleanedNumber.startsWith('90')) {
|
|
1051
|
+
// International format +90 or 90
|
|
1052
|
+
cleanedNumber = cleanedNumber.substring(2);
|
|
1053
|
+
}
|
|
1054
|
+
else if (cleanedNumber.startsWith('0')) {
|
|
1055
|
+
// National format 0
|
|
1056
|
+
cleanedNumber = cleanedNumber.substring(1);
|
|
1057
|
+
}
|
|
1058
|
+
// Validate Turkish mobile number pattern
|
|
1059
|
+
// Turkish mobile numbers start with 5 and are 10 digits total
|
|
1060
|
+
const turkishMobilePattern = /^5[0-9]{9}$/;
|
|
1061
|
+
if (!turkishMobilePattern.test(cleanedNumber)) {
|
|
1062
|
+
return {
|
|
1063
|
+
isValid: false,
|
|
1064
|
+
error: "Invalid Turkish GSM number format. Must be 10 digits starting with 5",
|
|
1065
|
+
originalNumber
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
// Additional validation for known Turkish mobile operators
|
|
1069
|
+
const operatorPrefixes = ['50', '51', '52', '53', '54', '55', '56', '57', '58', '59'];
|
|
1070
|
+
const prefix = cleanedNumber.substring(0, 2);
|
|
1071
|
+
if (!operatorPrefixes.includes(prefix)) {
|
|
1072
|
+
return {
|
|
1073
|
+
isValid: false,
|
|
1074
|
+
error: "Invalid Turkish mobile operator prefix",
|
|
1075
|
+
originalNumber
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
return {
|
|
1079
|
+
isValid: true,
|
|
1080
|
+
cleanedNumber: `+90${cleanedNumber}`,
|
|
1081
|
+
originalNumber
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
// INSTALLMENTS VALIDATION
|
|
1085
|
+
// Summary: Validates installment values and converts to standardized format
|
|
1086
|
+
// Description: Handles various input formats and validates against business rules
|
|
1087
|
+
/**
|
|
1088
|
+
* Validates installment values and converts to standardized format
|
|
1089
|
+
*
|
|
1090
|
+
* @summary Validates installment values and converts to standardized format
|
|
1091
|
+
* @description
|
|
1092
|
+
* Handles various input formats (string, number, array) and validates against
|
|
1093
|
+
* business rules. Converts single installment values to arrays and validates
|
|
1094
|
+
* that installment numbers are within acceptable ranges.
|
|
1095
|
+
*
|
|
1096
|
+
* Supported inputs:
|
|
1097
|
+
* - Single number: 3 -> [3]
|
|
1098
|
+
* - Comma-separated string: "1,3,6" -> [1,3,6]
|
|
1099
|
+
* - Array of numbers: [1,3,6,12] -> [1,3,6,12]
|
|
1100
|
+
* - Empty/null values default to [1]
|
|
1101
|
+
*
|
|
1102
|
+
* @param {string | number | number[]} installments - Installment values to validate
|
|
1103
|
+
* @returns {InstallmentsValidationResult} Validation result with standardized array
|
|
1104
|
+
*/
|
|
1105
|
+
function validateInstallments(installments) {
|
|
1106
|
+
const originalInput = installments;
|
|
1107
|
+
// Handle empty/null/undefined - default to single installment
|
|
1108
|
+
if (!installments || installments === '' || installments === null || installments === undefined || installments === 0) {
|
|
1109
|
+
return {
|
|
1110
|
+
isValid: true,
|
|
1111
|
+
validatedInstallments: [1],
|
|
1112
|
+
originalInput: String(originalInput)
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
let installmentArray = [];
|
|
1116
|
+
try {
|
|
1117
|
+
if (typeof installments === 'number') {
|
|
1118
|
+
// Single number
|
|
1119
|
+
installmentArray = [installments];
|
|
1120
|
+
}
|
|
1121
|
+
else if (typeof installments === 'string') {
|
|
1122
|
+
// Handle comma-separated string
|
|
1123
|
+
if (installments.includes(',')) {
|
|
1124
|
+
installmentArray = installments
|
|
1125
|
+
.split(',')
|
|
1126
|
+
.map(item => {
|
|
1127
|
+
const num = parseInt(item.trim(), 10);
|
|
1128
|
+
if (isNaN(num)) {
|
|
1129
|
+
throw new Error(`Invalid installment value: ${item.trim()}`);
|
|
1130
|
+
}
|
|
1131
|
+
return num;
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
else {
|
|
1135
|
+
// Single string number
|
|
1136
|
+
const num = parseInt(installments.trim(), 10);
|
|
1137
|
+
if (isNaN(num)) {
|
|
1138
|
+
throw new Error(`Invalid installment value: ${installments}`);
|
|
1139
|
+
}
|
|
1140
|
+
installmentArray = [num];
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
else if (Array.isArray(installments)) {
|
|
1144
|
+
// Array of numbers
|
|
1145
|
+
installmentArray = installments.map((item, index) => {
|
|
1146
|
+
if (typeof item !== 'number' || isNaN(item)) {
|
|
1147
|
+
throw new Error(`Invalid installment value at index ${index}: ${item}`);
|
|
1148
|
+
}
|
|
1149
|
+
return item;
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
return {
|
|
1154
|
+
isValid: false,
|
|
1155
|
+
validatedInstallments: [1],
|
|
1156
|
+
error: "Installments must be a number, string, or array of numbers",
|
|
1157
|
+
originalInput: String(originalInput)
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
// Validate installment values
|
|
1161
|
+
for (const installment of installmentArray) {
|
|
1162
|
+
if (!Number.isInteger(installment) || installment < 1) {
|
|
1163
|
+
return {
|
|
1164
|
+
isValid: false,
|
|
1165
|
+
validatedInstallments: [1],
|
|
1166
|
+
error: `Installment values must be positive integers, got: ${installment}`,
|
|
1167
|
+
originalInput: String(originalInput)
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
if (installment > 36) {
|
|
1171
|
+
return {
|
|
1172
|
+
isValid: false,
|
|
1173
|
+
validatedInstallments: [1],
|
|
1174
|
+
error: `Installment values cannot exceed 36, got: ${installment}`,
|
|
1175
|
+
originalInput: String(originalInput)
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// Remove duplicates and sort
|
|
1180
|
+
const uniqueInstallments = [...new Set(installmentArray)].sort((a, b) => a - b);
|
|
1181
|
+
return {
|
|
1182
|
+
isValid: true,
|
|
1183
|
+
validatedInstallments: uniqueInstallments,
|
|
1184
|
+
originalInput: String(originalInput)
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
catch (error) {
|
|
1188
|
+
return {
|
|
1189
|
+
isValid: false,
|
|
1190
|
+
validatedInstallments: [1],
|
|
1191
|
+
error: error instanceof Error ? error.message : "Unknown validation error",
|
|
1192
|
+
originalInput: String(originalInput)
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1020
1196
|
|
|
1021
1197
|
/**
|
|
1022
1198
|
* @category Configuration
|
|
@@ -1213,7 +1389,7 @@ class TapsilatSDK {
|
|
|
1213
1389
|
*
|
|
1214
1390
|
* @param {TapsilatConfig} config - SDK configuration options
|
|
1215
1391
|
* @param {string} config.bearerToken - API authentication token (required)
|
|
1216
|
-
* @param {string} [config.baseURL='https://
|
|
1392
|
+
* @param {string} [config.baseURL='https://panel.tapsilat.dev/v1'] - API base URL
|
|
1217
1393
|
* @param {number} [config.timeout=30000] - Request timeout in milliseconds
|
|
1218
1394
|
* @param {number} [config.maxRetries=3] - Maximum number of retry attempts
|
|
1219
1395
|
* @param {number} [config.retryDelay=1000] - Delay between retries in milliseconds
|
|
@@ -1234,71 +1410,65 @@ class TapsilatSDK {
|
|
|
1234
1410
|
/**
|
|
1235
1411
|
* Creates a new order and returns a checkout URL
|
|
1236
1412
|
*
|
|
1237
|
-
* @summary Initiates a new payment order with
|
|
1413
|
+
* @summary Initiates a new payment order with comprehensive order details
|
|
1238
1414
|
* @description
|
|
1239
1415
|
* Creates a new payment order in the Tapsilat system with the provided order details.
|
|
1240
1416
|
* This method performs comprehensive validation of all input parameters, creates the order
|
|
1241
|
-
* on the payment platform, and returns
|
|
1242
|
-
*
|
|
1243
|
-
* buyer information for compliance and fraud prevention.
|
|
1417
|
+
* on the payment platform, and returns order identifiers including reference_id and order_id.
|
|
1418
|
+
* The method supports multiple currencies, locales, payment options, basket items,
|
|
1419
|
+
* and comprehensive buyer information for compliance and fraud prevention.
|
|
1244
1420
|
*
|
|
1245
|
-
* The returned
|
|
1246
|
-
*
|
|
1247
|
-
* returned reference ID through the getOrderStatus method.
|
|
1421
|
+
* The returned order_id and reference_id can be used to track order status through
|
|
1422
|
+
* the getOrderStatus method.
|
|
1248
1423
|
*
|
|
1249
1424
|
* @param {OrderCreateRequest} orderRequest - Complete order information
|
|
1250
1425
|
* @param {number} orderRequest.amount - Payment amount (must be positive, max 2 decimal places)
|
|
1426
|
+
* @param {number} [orderRequest.tax_amount] - Tax amount included in total
|
|
1251
1427
|
* @param {Currency} orderRequest.currency - Payment currency ('TRY', 'USD', 'EUR', 'GBP')
|
|
1252
1428
|
* @param {Locale} orderRequest.locale - Display language ('tr' for Turkish, 'en' for English)
|
|
1429
|
+
* @param {boolean} [orderRequest.three_d_force] - Force 3D Secure authentication
|
|
1430
|
+
* @param {Address} [orderRequest.shipping_address] - Shipping address for delivery
|
|
1431
|
+
* @param {BasketItem[]} orderRequest.basket_items - Array of items in the order
|
|
1432
|
+
* @param {BillingAddress} orderRequest.billing_address - Billing address with tax information
|
|
1253
1433
|
* @param {Buyer} orderRequest.buyer - Customer information for payment processing
|
|
1254
|
-
* @param {string} orderRequest.
|
|
1255
|
-
* @param {
|
|
1256
|
-
* @param {
|
|
1257
|
-
* @param {
|
|
1258
|
-
* @param {string} [orderRequest.
|
|
1259
|
-
* @param {
|
|
1260
|
-
* @param {
|
|
1261
|
-
* @param {string} [orderRequest.description] - Order description for customer reference
|
|
1262
|
-
* @param {string} [orderRequest.callbackUrl] - URL to redirect after payment completion
|
|
1263
|
-
* @param {string} [orderRequest.conversationId] - Custom tracking ID for your system
|
|
1434
|
+
* @param {string} [orderRequest.conversation_id] - Custom tracking ID for your system
|
|
1435
|
+
* @param {boolean} [orderRequest.partial_payment] - Enable partial payment
|
|
1436
|
+
* @param {boolean} [orderRequest.payment_methods] - Enable payment method selection
|
|
1437
|
+
* @param {PaymentOption[]} [orderRequest.payment_options] - Available payment options
|
|
1438
|
+
* @param {string} [orderRequest.payment_success_url] - URL to redirect after successful payment
|
|
1439
|
+
* @param {string} [orderRequest.payment_failure_url] - URL to redirect after failed payment
|
|
1440
|
+
* @param {number[]} [orderRequest.enabled_installments] - Allowed installment counts
|
|
1264
1441
|
* @param {Record<string, unknown>} [orderRequest.metadata] - Additional custom data
|
|
1265
1442
|
*
|
|
1266
1443
|
* @returns {Promise<OrderCreateResponse>} Promise resolving to order creation response
|
|
1267
|
-
* @returns {string} OrderCreateResponse.
|
|
1268
|
-
* @returns {string} OrderCreateResponse.
|
|
1269
|
-
* @returns {string} OrderCreateResponse.
|
|
1270
|
-
* @returns {string} OrderCreateResponse.
|
|
1271
|
-
* @returns {string} [OrderCreateResponse.
|
|
1444
|
+
* @returns {string} OrderCreateResponse.order_id - Internal order identifier
|
|
1445
|
+
* @returns {string} OrderCreateResponse.reference_id - Unique order reference for tracking
|
|
1446
|
+
* @returns {string} [OrderCreateResponse.checkout_url] - Payment page URL for customer
|
|
1447
|
+
* @returns {string} [OrderCreateResponse.conversation_id] - Echo of provided conversation ID
|
|
1448
|
+
* @returns {string} [OrderCreateResponse.status] - Initial order status
|
|
1449
|
+
* @returns {string} [OrderCreateResponse.qr_code_url] - QR code URL for mobile payments
|
|
1272
1450
|
*
|
|
1273
1451
|
* @throws {TapsilatValidationError} When input validation fails:
|
|
1274
1452
|
* - Amount is not positive or has more than 2 decimal places
|
|
1275
1453
|
* - Currency is not supported
|
|
1276
1454
|
* - Buyer information is incomplete or invalid
|
|
1277
|
-
* -
|
|
1455
|
+
* - Basket items are missing or invalid
|
|
1456
|
+
* - Billing address is missing
|
|
1278
1457
|
* - Required fields are missing
|
|
1279
|
-
* @throws {TapsilatNetworkError} When network request fails
|
|
1280
|
-
*
|
|
1281
|
-
* - DNS resolution failure
|
|
1282
|
-
* - Network connectivity issues
|
|
1283
|
-
* @throws {TapsilatError} When API returns business logic errors:
|
|
1284
|
-
* - Insufficient merchant balance
|
|
1285
|
-
* - Currency not enabled for merchant
|
|
1286
|
-
* - Buyer blocked due to fraud detection
|
|
1287
|
-
* - Rate limiting exceeded
|
|
1458
|
+
* @throws {TapsilatNetworkError} When network request fails
|
|
1459
|
+
* @throws {TapsilatError} When API returns business logic errors
|
|
1288
1460
|
*/
|
|
1289
1461
|
async createOrder(orderRequest) {
|
|
1290
|
-
// Validate the order request
|
|
1291
|
-
// Check if request is null/undefined
|
|
1462
|
+
// Validate the order request
|
|
1292
1463
|
if (!orderRequest) {
|
|
1293
1464
|
throw new TapsilatValidationError("Order request cannot be null or undefined");
|
|
1294
1465
|
}
|
|
1295
|
-
// Validate amount
|
|
1466
|
+
// Validate amount
|
|
1296
1467
|
if (!isPositiveNumber(orderRequest.amount)) {
|
|
1297
1468
|
throw new TapsilatValidationError("Amount must be a positive number", {
|
|
1298
1469
|
provided: orderRequest.amount,
|
|
1299
1470
|
});
|
|
1300
1471
|
}
|
|
1301
|
-
// Validate amount - check decimal places
|
|
1302
1472
|
if (!hasValidDecimalPlaces(orderRequest.amount)) {
|
|
1303
1473
|
throw new TapsilatValidationError("Amount must have maximum 2 decimal places", { provided: orderRequest.amount });
|
|
1304
1474
|
}
|
|
@@ -1306,6 +1476,10 @@ class TapsilatSDK {
|
|
|
1306
1476
|
if (!isNonEmptyString(orderRequest.currency)) {
|
|
1307
1477
|
throw new TapsilatValidationError("Currency is required and must be a non-empty string", { provided: orderRequest.currency });
|
|
1308
1478
|
}
|
|
1479
|
+
// Validate locale
|
|
1480
|
+
if (!isNonEmptyString(orderRequest.locale)) {
|
|
1481
|
+
throw new TapsilatValidationError("Locale is required and must be a non-empty string", { provided: orderRequest.locale });
|
|
1482
|
+
}
|
|
1309
1483
|
// Validate buyer information
|
|
1310
1484
|
if (!orderRequest.buyer) {
|
|
1311
1485
|
throw new TapsilatValidationError("Buyer information is required");
|
|
@@ -1317,14 +1491,20 @@ class TapsilatSDK {
|
|
|
1317
1491
|
if (!isNonEmptyString(buyer.surname)) {
|
|
1318
1492
|
throw new TapsilatValidationError("Buyer surname is required and must be a non-empty string", { provided: buyer.surname });
|
|
1319
1493
|
}
|
|
1320
|
-
// Validate buyer email - check if provided
|
|
1321
1494
|
if (!isNonEmptyString(buyer.email)) {
|
|
1322
1495
|
throw new TapsilatValidationError("Buyer email is required and must be a non-empty string", { provided: buyer.email });
|
|
1323
1496
|
}
|
|
1324
|
-
// Validate buyer email - check format
|
|
1325
1497
|
if (!isValidEmail(buyer.email)) {
|
|
1326
1498
|
throw new TapsilatValidationError("Buyer email must be a valid email address", { provided: buyer.email });
|
|
1327
1499
|
}
|
|
1500
|
+
// Validate basket items
|
|
1501
|
+
if (!orderRequest.basket_items || !Array.isArray(orderRequest.basket_items) || orderRequest.basket_items.length === 0) {
|
|
1502
|
+
throw new TapsilatValidationError("Basket items are required and must be a non-empty array");
|
|
1503
|
+
}
|
|
1504
|
+
// Validate billing address
|
|
1505
|
+
if (!orderRequest.billing_address) {
|
|
1506
|
+
throw new TapsilatValidationError("Billing address is required");
|
|
1507
|
+
}
|
|
1328
1508
|
try {
|
|
1329
1509
|
// Make the API request
|
|
1330
1510
|
const createOrderResponse = await this.httpClient.post("/order/create", orderRequest);
|
|
@@ -1764,7 +1944,261 @@ class TapsilatSDK {
|
|
|
1764
1944
|
getConfigManager() {
|
|
1765
1945
|
return this.configManager;
|
|
1766
1946
|
}
|
|
1947
|
+
// PAYMENT TERM MANAGEMENT
|
|
1948
|
+
// Summary: Create, update, delete, and manage payment terms for orders
|
|
1949
|
+
// Description: Full lifecycle management of payment terms including installments and refunds
|
|
1950
|
+
/**
|
|
1951
|
+
* Creates a new payment term for an existing order
|
|
1952
|
+
*
|
|
1953
|
+
* @summary Create payment term for installment or partial payment
|
|
1954
|
+
* @description
|
|
1955
|
+
* Creates a new payment term for an existing order, enabling installment payments
|
|
1956
|
+
* or partial payment collection. Payment terms allow splitting order amounts
|
|
1957
|
+
* across multiple payments with specific due dates and requirements.
|
|
1958
|
+
*
|
|
1959
|
+
* @param {OrderPaymentTermCreateDTO} termData - Payment term creation data
|
|
1960
|
+
* @param {string} termData.order_id - Reference ID of the existing order
|
|
1961
|
+
* @param {string} termData.term_reference_id - Unique identifier for this payment term
|
|
1962
|
+
* @param {number} termData.amount - Amount for this payment term
|
|
1963
|
+
* @param {string} termData.due_date - Due date for this payment (ISO 8601 format)
|
|
1964
|
+
* @param {number} termData.term_sequence - Sequence number for this term
|
|
1965
|
+
* @param {boolean} termData.required - Whether this payment term is required
|
|
1966
|
+
* @param {string} termData.status - Initial status of the payment term
|
|
1967
|
+
* @param {string} [termData.data] - Additional metadata for the term
|
|
1968
|
+
* @param {string} [termData.paid_date] - Date when payment was completed
|
|
1969
|
+
*
|
|
1970
|
+
* @returns {Promise<PaymentTermResponse>} Promise resolving to created payment term details
|
|
1971
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
1972
|
+
* @throws {TapsilatError} When API returns an error response
|
|
1973
|
+
*/
|
|
1974
|
+
async createOrderTerm(termData) {
|
|
1975
|
+
// Validate required fields
|
|
1976
|
+
if (!isNonEmptyString(termData.order_id)) {
|
|
1977
|
+
throw new TapsilatValidationError("Order ID is required and must be a non-empty string", { provided: termData.order_id });
|
|
1978
|
+
}
|
|
1979
|
+
if (!isNonEmptyString(termData.term_reference_id)) {
|
|
1980
|
+
throw new TapsilatValidationError("Term reference ID is required and must be a non-empty string", { provided: termData.term_reference_id });
|
|
1981
|
+
}
|
|
1982
|
+
if (!isPositiveNumber(termData.amount)) {
|
|
1983
|
+
throw new TapsilatValidationError("Amount must be a positive number", {
|
|
1984
|
+
provided: termData.amount,
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
if (!hasValidDecimalPlaces(termData.amount)) {
|
|
1988
|
+
throw new TapsilatValidationError("Amount must have maximum 2 decimal places", { provided: termData.amount });
|
|
1989
|
+
}
|
|
1990
|
+
if (!isNonEmptyString(termData.due_date)) {
|
|
1991
|
+
throw new TapsilatValidationError("Due date is required and must be a non-empty string", { provided: termData.due_date });
|
|
1992
|
+
}
|
|
1993
|
+
if (!isInteger(termData.term_sequence)) {
|
|
1994
|
+
throw new TapsilatValidationError("Term sequence must be an integer", {
|
|
1995
|
+
provided: termData.term_sequence,
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
if (typeof termData.required !== "boolean") {
|
|
1999
|
+
throw new TapsilatValidationError("Required field must be a boolean", {
|
|
2000
|
+
provided: termData.required,
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
if (!isNonEmptyString(termData.status)) {
|
|
2004
|
+
throw new TapsilatValidationError("Status is required and must be a non-empty string", { provided: termData.status });
|
|
2005
|
+
}
|
|
2006
|
+
try {
|
|
2007
|
+
const createTermResponse = await this.httpClient.post("/order/term/create", termData);
|
|
2008
|
+
return handleResponse(createTermResponse, "Payment term creation");
|
|
2009
|
+
}
|
|
2010
|
+
catch (error) {
|
|
2011
|
+
return handleError(error, "payment term creation");
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Updates an existing payment term
|
|
2016
|
+
*
|
|
2017
|
+
* @summary Update payment term details
|
|
2018
|
+
* @description
|
|
2019
|
+
* Updates an existing payment term with new information such as amount,
|
|
2020
|
+
* due date, status, or other metadata. This allows for flexible management
|
|
2021
|
+
* of installment payments and payment schedules.
|
|
2022
|
+
*
|
|
2023
|
+
* @param {OrderPaymentTermUpdateDTO} updateData - Payment term update data
|
|
2024
|
+
* @param {string} updateData.term_reference_id - Reference ID of the term to update
|
|
2025
|
+
* @param {number} [updateData.amount] - New amount for the payment term
|
|
2026
|
+
* @param {string} [updateData.due_date] - New due date (ISO 8601 format)
|
|
2027
|
+
* @param {string} [updateData.paid_date] - Date when payment was completed
|
|
2028
|
+
* @param {boolean} [updateData.required] - Whether this payment term is required
|
|
2029
|
+
* @param {string} [updateData.status] - New status of the payment term
|
|
2030
|
+
* @param {number} [updateData.term_sequence] - New sequence number
|
|
2031
|
+
*
|
|
2032
|
+
* @returns {Promise<PaymentTermResponse>} Promise resolving to updated payment term details
|
|
2033
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
2034
|
+
* @throws {TapsilatError} When API returns an error response
|
|
2035
|
+
*/
|
|
2036
|
+
async updateOrderTerm(updateData) {
|
|
2037
|
+
// Validate required fields
|
|
2038
|
+
if (!isNonEmptyString(updateData.term_reference_id)) {
|
|
2039
|
+
throw new TapsilatValidationError("Term reference ID is required and must be a non-empty string", { provided: updateData.term_reference_id });
|
|
2040
|
+
}
|
|
2041
|
+
// Validate optional amount if provided
|
|
2042
|
+
if (updateData.amount !== undefined) {
|
|
2043
|
+
if (!isPositiveNumber(updateData.amount)) {
|
|
2044
|
+
throw new TapsilatValidationError("Amount must be a positive number", {
|
|
2045
|
+
provided: updateData.amount,
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
if (!hasValidDecimalPlaces(updateData.amount)) {
|
|
2049
|
+
throw new TapsilatValidationError("Amount must have maximum 2 decimal places", { provided: updateData.amount });
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
// Validate optional term sequence if provided
|
|
2053
|
+
if (updateData.term_sequence !== undefined) {
|
|
2054
|
+
if (!isInteger(updateData.term_sequence)) {
|
|
2055
|
+
throw new TapsilatValidationError("Term sequence must be an integer", {
|
|
2056
|
+
provided: updateData.term_sequence,
|
|
2057
|
+
});
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
// Validate optional required field if provided
|
|
2061
|
+
if (updateData.required !== undefined &&
|
|
2062
|
+
typeof updateData.required !== "boolean") {
|
|
2063
|
+
throw new TapsilatValidationError("Required field must be a boolean", {
|
|
2064
|
+
provided: updateData.required,
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
try {
|
|
2068
|
+
const updateTermResponse = await this.httpClient.post("/order/term/update", updateData);
|
|
2069
|
+
return handleResponse(updateTermResponse, "Payment term update");
|
|
2070
|
+
}
|
|
2071
|
+
catch (error) {
|
|
2072
|
+
return handleError(error, "payment term update");
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
/**
|
|
2076
|
+
* Deletes a payment term
|
|
2077
|
+
*
|
|
2078
|
+
* @summary Delete payment term
|
|
2079
|
+
* @description
|
|
2080
|
+
* Permanently deletes a payment term from an order. This action cannot be undone.
|
|
2081
|
+
* Only unpaid payment terms can be deleted.
|
|
2082
|
+
*
|
|
2083
|
+
* @param {PaymentTermDeleteRequest} deleteData - Payment term deletion data
|
|
2084
|
+
* @param {string} deleteData.term_reference_id - Reference ID of the term to delete
|
|
2085
|
+
*
|
|
2086
|
+
* @returns {Promise<PaymentTermResponse>} Promise resolving to deleted payment term details
|
|
2087
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
2088
|
+
* @throws {TapsilatError} When API returns an error response
|
|
2089
|
+
*/
|
|
2090
|
+
async deleteOrderTerm(deleteData) {
|
|
2091
|
+
// Validate required fields
|
|
2092
|
+
if (!isNonEmptyString(deleteData.term_reference_id)) {
|
|
2093
|
+
throw new TapsilatValidationError("Term reference ID is required and must be a non-empty string", { provided: deleteData.term_reference_id });
|
|
2094
|
+
}
|
|
2095
|
+
try {
|
|
2096
|
+
const deleteTermResponse = await this.httpClient.post("/order/term/delete", deleteData);
|
|
2097
|
+
return handleResponse(deleteTermResponse, "Payment term deletion");
|
|
2098
|
+
}
|
|
2099
|
+
catch (error) {
|
|
2100
|
+
return handleError(error, "payment term deletion");
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
/**
|
|
2104
|
+
* Refunds a specific payment term
|
|
2105
|
+
*
|
|
2106
|
+
* @summary Refund payment term
|
|
2107
|
+
* @description
|
|
2108
|
+
* Processes a refund for a specific payment term. This allows partial refunds
|
|
2109
|
+
* at the payment term level rather than the entire order level.
|
|
2110
|
+
*
|
|
2111
|
+
* @param {OrderTermRefundRequest} refundData - Payment term refund data
|
|
2112
|
+
* @param {string} refundData.term_id - ID of the term to refund
|
|
2113
|
+
* @param {number} refundData.amount - Amount to refund
|
|
2114
|
+
* @param {string} [refundData.reference_id] - Optional reference ID
|
|
2115
|
+
* @param {string} [refundData.term_payment_id] - Optional term payment ID
|
|
2116
|
+
*
|
|
2117
|
+
* @returns {Promise<PaymentTermRefundResponse>} Promise resolving to refund details
|
|
2118
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
2119
|
+
* @throws {TapsilatError} When API returns an error response
|
|
2120
|
+
*/
|
|
2121
|
+
async refundOrderTerm(refundData) {
|
|
2122
|
+
// Validate required fields
|
|
2123
|
+
if (!isNonEmptyString(refundData.term_id)) {
|
|
2124
|
+
throw new TapsilatValidationError("Term ID is required and must be a non-empty string", { provided: refundData.term_id });
|
|
2125
|
+
}
|
|
2126
|
+
if (!isPositiveNumber(refundData.amount)) {
|
|
2127
|
+
throw new TapsilatValidationError("Amount must be a positive number", {
|
|
2128
|
+
provided: refundData.amount,
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
2131
|
+
if (!hasValidDecimalPlaces(refundData.amount)) {
|
|
2132
|
+
throw new TapsilatValidationError("Amount must have maximum 2 decimal places", { provided: refundData.amount });
|
|
2133
|
+
}
|
|
2134
|
+
try {
|
|
2135
|
+
const refundTermResponse = await this.httpClient.post("/order/term/refund", refundData);
|
|
2136
|
+
return handleResponse(refundTermResponse, "Payment term refund");
|
|
2137
|
+
}
|
|
2138
|
+
catch (error) {
|
|
2139
|
+
return handleError(error, "payment term refund");
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* Terminates a payment term
|
|
2144
|
+
*
|
|
2145
|
+
* @summary Terminate payment term
|
|
2146
|
+
* @description
|
|
2147
|
+
* Terminates an active payment term, preventing further payments.
|
|
2148
|
+
* This is useful for canceling installment plans or payment schedules.
|
|
2149
|
+
*
|
|
2150
|
+
* @param {PaymentTermTerminateRequest} terminateData - Payment term termination data
|
|
2151
|
+
* @param {string} terminateData.term_reference_id - Reference ID of the term to terminate
|
|
2152
|
+
* @param {string} [terminateData.reason] - Optional reason for termination
|
|
2153
|
+
*
|
|
2154
|
+
* @returns {Promise<PaymentTermResponse>} Promise resolving to terminated term details
|
|
2155
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
2156
|
+
* @throws {TapsilatError} When API returns an error response
|
|
2157
|
+
*/
|
|
2158
|
+
async terminateOrderTerm(terminateData) {
|
|
2159
|
+
// Validate required fields
|
|
2160
|
+
if (!isNonEmptyString(terminateData.term_reference_id)) {
|
|
2161
|
+
throw new TapsilatValidationError("Term reference ID is required and must be a non-empty string", { provided: terminateData.term_reference_id });
|
|
2162
|
+
}
|
|
2163
|
+
try {
|
|
2164
|
+
const terminateTermResponse = await this.httpClient.post("/order/term/terminate", terminateData);
|
|
2165
|
+
return handleResponse(terminateTermResponse, "Payment term termination");
|
|
2166
|
+
}
|
|
2167
|
+
catch (error) {
|
|
2168
|
+
return handleError(error, "payment term termination");
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Terminates an entire order
|
|
2173
|
+
*
|
|
2174
|
+
* @summary Terminate order
|
|
2175
|
+
* @description
|
|
2176
|
+
* Terminates an entire order, canceling all associated payment terms and
|
|
2177
|
+
* preventing any further payment processing. This is a more comprehensive
|
|
2178
|
+
* action than canceling individual payment terms.
|
|
2179
|
+
*
|
|
2180
|
+
* @param {OrderTerminateRequest} terminateData - Order termination data
|
|
2181
|
+
* @param {string} terminateData.reference_id - Reference ID of the order to terminate
|
|
2182
|
+
* @param {string} [terminateData.reason] - Optional reason for termination
|
|
2183
|
+
*
|
|
2184
|
+
* @returns {Promise<OrderTerminateResponse>} Promise resolving to terminated order details
|
|
2185
|
+
* @throws {TapsilatValidationError} When input validation fails
|
|
2186
|
+
* @throws {TapsilatError} When API returns an error response
|
|
2187
|
+
*/
|
|
2188
|
+
async terminateOrder(terminateData) {
|
|
2189
|
+
// Validate required fields
|
|
2190
|
+
if (!isNonEmptyString(terminateData.reference_id)) {
|
|
2191
|
+
throw new TapsilatValidationError("Reference ID is required and must be a non-empty string", { provided: terminateData.reference_id });
|
|
2192
|
+
}
|
|
2193
|
+
try {
|
|
2194
|
+
const terminateOrderResponse = await this.httpClient.post("/order/terminate", terminateData);
|
|
2195
|
+
return handleResponse(terminateOrderResponse, "Order termination");
|
|
2196
|
+
}
|
|
2197
|
+
catch (error) {
|
|
2198
|
+
return handleError(error, "order termination");
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
1767
2201
|
}
|
|
1768
2202
|
|
|
1769
|
-
export { ConfigManager, TapsilatAuthenticationError, TapsilatError, TapsilatNetworkError, TapsilatRateLimitError, TapsilatSDK, TapsilatValidationError, isValidCurrency, isValidPaymentMethod, isValidUrl, sanitizeMetadata, validateEmail, validatePaymentRequest };
|
|
2203
|
+
export { ConfigManager, TapsilatAuthenticationError, TapsilatError, TapsilatNetworkError, TapsilatRateLimitError, TapsilatSDK, TapsilatValidationError, isValidCurrency, isValidPaymentMethod, isValidUrl, sanitizeMetadata, validateEmail, validateGsmNumber, validateInstallments, validatePaymentRequest };
|
|
1770
2204
|
//# sourceMappingURL=index.esm.js.map
|