vesant-sdk 1.6.0 → 1.6.2
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/dist/{client-C4g596fI.d.mts → client-BlCxjbY2.d.mts} +8 -2
- package/dist/{client-Bd9a5o0C.d.ts → client-C_A7QLcB.d.ts} +8 -2
- package/dist/{client-CIon-bGS.d.mts → client-ePzhQKp9.d.mts} +2 -0
- package/dist/{client-CIon-bGS.d.ts → client-ePzhQKp9.d.ts} +2 -0
- package/dist/compliance/index.d.mts +12 -5
- package/dist/compliance/index.d.ts +12 -5
- package/dist/compliance/index.js +201 -69
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +201 -69
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/decisions/index.d.mts +1 -1
- package/dist/decisions/index.d.ts +1 -1
- package/dist/decisions/index.js +14 -1
- package/dist/decisions/index.js.map +1 -1
- package/dist/decisions/index.mjs +14 -1
- package/dist/decisions/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +3 -3
- package/dist/geolocation/index.d.ts +3 -3
- package/dist/geolocation/index.js +56 -14
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +56 -14
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -376
- package/dist/index.d.ts +6 -376
- package/dist/index.js +268 -278
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +268 -278
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.d.mts +1 -1
- package/dist/kyc/core.d.ts +1 -1
- package/dist/kyc/core.js +14 -1
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +14 -1
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.d.mts +1 -1
- package/dist/kyc/index.d.ts +1 -1
- package/dist/kyc/index.js +14 -1
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +14 -1
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1 -1
- package/dist/react.mjs.map +1 -1
- package/dist/risk-profile/index.d.mts +1 -1
- package/dist/risk-profile/index.d.ts +1 -1
- package/dist/risk-profile/index.js +14 -1
- package/dist/risk-profile/index.js.map +1 -1
- package/dist/risk-profile/index.mjs +14 -1
- package/dist/risk-profile/index.mjs.map +1 -1
- package/dist/scores/index.d.mts +1 -1
- package/dist/scores/index.d.ts +1 -1
- package/dist/scores/index.js +14 -1
- package/dist/scores/index.js.map +1 -1
- package/dist/scores/index.mjs +14 -1
- package/dist/scores/index.mjs.map +1 -1
- package/dist/tax/index.d.mts +255 -0
- package/dist/tax/index.d.ts +255 -0
- package/dist/tax/index.js +652 -0
- package/dist/tax/index.js.map +1 -0
- package/dist/tax/index.mjs +650 -0
- package/dist/tax/index.mjs.map +1 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -240,7 +240,7 @@ var noopLogger = {
|
|
|
240
240
|
};
|
|
241
241
|
|
|
242
242
|
// src/core/version.ts
|
|
243
|
-
var SDK_VERSION = "1.6.
|
|
243
|
+
var SDK_VERSION = "1.6.2";
|
|
244
244
|
|
|
245
245
|
// src/shared/browser-utils.ts
|
|
246
246
|
function generateUUID() {
|
|
@@ -414,6 +414,19 @@ var BaseClient = class {
|
|
|
414
414
|
if (this.rateLimitTracker) {
|
|
415
415
|
this.rateLimitTracker.updateFromHeaders(response.headers);
|
|
416
416
|
}
|
|
417
|
+
if (requestOptions?.responseType === "arraybuffer") {
|
|
418
|
+
if (!response.ok) {
|
|
419
|
+
let errData = {};
|
|
420
|
+
try {
|
|
421
|
+
errData = await response.json();
|
|
422
|
+
} catch {
|
|
423
|
+
}
|
|
424
|
+
this.handleErrorResponse(response.status, errData, requestId);
|
|
425
|
+
}
|
|
426
|
+
this.circuitBreaker?.onSuccess();
|
|
427
|
+
const buffer = await response.arrayBuffer();
|
|
428
|
+
return buffer;
|
|
429
|
+
}
|
|
417
430
|
let data;
|
|
418
431
|
try {
|
|
419
432
|
data = await response.json();
|
|
@@ -1108,22 +1121,51 @@ var GeolocationClient = class extends BaseClient {
|
|
|
1108
1121
|
void 0,
|
|
1109
1122
|
requestOptions
|
|
1110
1123
|
);
|
|
1111
|
-
const
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1124
|
+
const loc = cipherTextResult.location;
|
|
1125
|
+
const risk = cipherTextResult.risk;
|
|
1126
|
+
if (!risk) {
|
|
1127
|
+
const locationResult = await this.verifyIP({
|
|
1128
|
+
ip_address: ipAddress,
|
|
1129
|
+
user_id: userId,
|
|
1130
|
+
event_type: eventType
|
|
1131
|
+
}, requestOptions);
|
|
1132
|
+
return {
|
|
1133
|
+
ciphertext_valid: cipherTextResult.valid,
|
|
1134
|
+
ciphertext_result: cipherTextResult,
|
|
1135
|
+
location: locationResult
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
const location = {
|
|
1139
|
+
ip_address: cipherTextResult.ip_address,
|
|
1140
|
+
location: {
|
|
1141
|
+
country: loc?.country ?? "",
|
|
1142
|
+
country_iso: loc?.country_iso ?? "",
|
|
1143
|
+
city: loc?.city ?? "",
|
|
1144
|
+
region: loc?.region ?? "",
|
|
1145
|
+
postal_code: "",
|
|
1146
|
+
latitude: loc?.latitude ?? 0,
|
|
1147
|
+
longitude: loc?.longitude ?? 0,
|
|
1148
|
+
timezone: "",
|
|
1149
|
+
is_vpn: risk.is_vpn ?? false,
|
|
1150
|
+
is_proxy: risk.is_proxy ?? false,
|
|
1151
|
+
is_tor: risk.is_tor ?? false,
|
|
1152
|
+
is_hosting: risk.is_hosting ?? false,
|
|
1153
|
+
is_anonymizer: risk.is_vpn || risk.is_proxy || risk.is_tor
|
|
1154
|
+
},
|
|
1155
|
+
is_compliant: cipherTextResult.is_compliant ?? !risk.is_blocked,
|
|
1156
|
+
is_blocked: risk.is_blocked ?? false,
|
|
1157
|
+
risk_level: risk.level ?? "low",
|
|
1158
|
+
risk_score: risk.score ?? 0,
|
|
1159
|
+
risk_reasons: risk.is_blocked && risk.block_reasons ? risk.block_reasons : risk.factors ?? [],
|
|
1160
|
+
jurisdiction: cipherTextResult.jurisdiction,
|
|
1161
|
+
geofence_evaluation: cipherTextResult.geofence_evaluation,
|
|
1162
|
+
record_id: cipherTextResult.record_id ?? "",
|
|
1163
|
+
gps_required: cipherTextResult.gps_required
|
|
1164
|
+
};
|
|
1123
1165
|
return {
|
|
1124
1166
|
ciphertext_valid: cipherTextResult.valid,
|
|
1125
1167
|
ciphertext_result: cipherTextResult,
|
|
1126
|
-
location
|
|
1168
|
+
location
|
|
1127
1169
|
};
|
|
1128
1170
|
}
|
|
1129
1171
|
// ============================================================================
|
|
@@ -1528,28 +1570,34 @@ var ComplianceClient = class {
|
|
|
1528
1570
|
if (this.config.debug) {
|
|
1529
1571
|
this.logger.debug("Starting registration verification", { customerId: request.customerId });
|
|
1530
1572
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
email: request.emailAddress,
|
|
1534
|
-
phone: request.phoneNumber,
|
|
1535
|
-
date_of_birth: request.dateOfBirth
|
|
1536
|
-
} : void 0;
|
|
1537
|
-
[cipherTextResult, geoVerification] = await Promise.all([
|
|
1538
|
-
this.executeCipherTextValidation(
|
|
1573
|
+
if (request.cipherText) {
|
|
1574
|
+
cipherTextResult = await this.executeCipherTextValidation(
|
|
1539
1575
|
request.cipherText,
|
|
1540
1576
|
request.customerId,
|
|
1541
1577
|
"registration",
|
|
1542
1578
|
request.ipAddress,
|
|
1543
|
-
|
|
1579
|
+
{
|
|
1580
|
+
full_name: request.fullName,
|
|
1581
|
+
email: request.emailAddress,
|
|
1582
|
+
phone: request.phoneNumber,
|
|
1583
|
+
date_of_birth: request.dateOfBirth
|
|
1584
|
+
},
|
|
1544
1585
|
requestOptions
|
|
1545
|
-
)
|
|
1546
|
-
this.geoClient.verifyIP({
|
|
1586
|
+
);
|
|
1587
|
+
geoVerification = (cipherTextResult && this.buildLocationFromCipherText(cipherTextResult, request.ipAddress)) ?? await this.geoClient.verifyIP({
|
|
1547
1588
|
ip_address: request.ipAddress,
|
|
1548
1589
|
user_id: request.customerId,
|
|
1549
1590
|
event_type: "registration",
|
|
1550
1591
|
device_fingerprint: request.deviceFingerprint
|
|
1551
|
-
}, requestOptions)
|
|
1552
|
-
|
|
1592
|
+
}, requestOptions);
|
|
1593
|
+
} else {
|
|
1594
|
+
geoVerification = await this.geoClient.verifyIP({
|
|
1595
|
+
ip_address: request.ipAddress,
|
|
1596
|
+
user_id: request.customerId,
|
|
1597
|
+
event_type: "registration",
|
|
1598
|
+
device_fingerprint: request.deviceFingerprint
|
|
1599
|
+
}, requestOptions);
|
|
1600
|
+
}
|
|
1553
1601
|
const blockReasons = this.evaluateRegistrationBlock(geoVerification, cipherTextResult);
|
|
1554
1602
|
if (blockReasons.length > 0) {
|
|
1555
1603
|
if (this.config.debug) {
|
|
@@ -1630,7 +1678,7 @@ var ComplianceClient = class {
|
|
|
1630
1678
|
evaluateRegistrationBlock(geoVerification, cipherTextResult) {
|
|
1631
1679
|
const blockReasons = [];
|
|
1632
1680
|
if (geoVerification.is_blocked) {
|
|
1633
|
-
blockReasons.push(...geoVerification.risk_reasons);
|
|
1681
|
+
blockReasons.push(...geoVerification.risk_reasons ?? []);
|
|
1634
1682
|
}
|
|
1635
1683
|
if (!geoVerification.is_compliant) {
|
|
1636
1684
|
if (!blockReasons.includes("non_compliant_jurisdiction")) {
|
|
@@ -1654,7 +1702,7 @@ var ComplianceClient = class {
|
|
|
1654
1702
|
}
|
|
1655
1703
|
}
|
|
1656
1704
|
if (geoVerification.geofence_evaluation?.blocked) {
|
|
1657
|
-
blockReasons.push(...geoVerification.geofence_evaluation.reasons);
|
|
1705
|
+
blockReasons.push(...geoVerification.geofence_evaluation.reasons ?? []);
|
|
1658
1706
|
}
|
|
1659
1707
|
if (geoVerification.risk_level === "critical") {
|
|
1660
1708
|
if (!blockReasons.includes("critical_risk_level")) {
|
|
@@ -1805,24 +1853,40 @@ var ComplianceClient = class {
|
|
|
1805
1853
|
if (this.config.debug) {
|
|
1806
1854
|
this.logger.debug("Starting login verification", { customerId: request.customerId });
|
|
1807
1855
|
}
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1856
|
+
let cipherTextResult;
|
|
1857
|
+
let geoVerification;
|
|
1858
|
+
let profileResult;
|
|
1859
|
+
if (request.cipherText) {
|
|
1860
|
+
[cipherTextResult, profileResult] = await Promise.all([
|
|
1861
|
+
this.executeCipherTextValidation(
|
|
1862
|
+
request.cipherText,
|
|
1863
|
+
request.customerId,
|
|
1864
|
+
"login",
|
|
1865
|
+
request.ipAddress,
|
|
1866
|
+
void 0,
|
|
1867
|
+
requestOptions
|
|
1868
|
+
),
|
|
1869
|
+
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
1870
|
+
]);
|
|
1871
|
+
geoVerification = (cipherTextResult && this.buildLocationFromCipherText(cipherTextResult, request.ipAddress)) ?? await this.geoClient.verifyIP({
|
|
1818
1872
|
ip_address: request.ipAddress,
|
|
1819
1873
|
user_id: request.customerId,
|
|
1820
1874
|
event_type: "login",
|
|
1821
1875
|
device_fingerprint: request.deviceFingerprint
|
|
1822
|
-
}, requestOptions)
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1876
|
+
}, requestOptions);
|
|
1877
|
+
} else {
|
|
1878
|
+
[, geoVerification, profileResult] = await Promise.all([
|
|
1879
|
+
Promise.resolve(void 0),
|
|
1880
|
+
this.geoClient.verifyIP({
|
|
1881
|
+
ip_address: request.ipAddress,
|
|
1882
|
+
user_id: request.customerId,
|
|
1883
|
+
event_type: "login",
|
|
1884
|
+
device_fingerprint: request.deviceFingerprint
|
|
1885
|
+
}, requestOptions),
|
|
1886
|
+
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
1887
|
+
]);
|
|
1888
|
+
}
|
|
1889
|
+
const loginBlockReasons = this.getBlockReasons(geoVerification, profileResult, cipherTextResult);
|
|
1826
1890
|
const isBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
|
|
1827
1891
|
if (isBlocked && !profileResult) {
|
|
1828
1892
|
return {
|
|
@@ -1906,23 +1970,39 @@ var ComplianceClient = class {
|
|
|
1906
1970
|
currency: request.currency
|
|
1907
1971
|
});
|
|
1908
1972
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1973
|
+
let cipherTextResult;
|
|
1974
|
+
let geoVerification;
|
|
1975
|
+
let profileResult;
|
|
1976
|
+
if (request.cipherText) {
|
|
1977
|
+
[cipherTextResult, profileResult] = await Promise.all([
|
|
1978
|
+
this.executeCipherTextValidation(
|
|
1979
|
+
request.cipherText,
|
|
1980
|
+
request.customerId,
|
|
1981
|
+
"transaction",
|
|
1982
|
+
request.ipAddress,
|
|
1983
|
+
void 0,
|
|
1984
|
+
requestOptions
|
|
1985
|
+
),
|
|
1986
|
+
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
1987
|
+
]);
|
|
1988
|
+
geoVerification = (cipherTextResult && this.buildLocationFromCipherText(cipherTextResult, request.ipAddress)) ?? await this.geoClient.verifyIP({
|
|
1919
1989
|
ip_address: request.ipAddress,
|
|
1920
1990
|
user_id: request.customerId,
|
|
1921
1991
|
event_type: "transaction",
|
|
1922
1992
|
device_fingerprint: request.deviceFingerprint
|
|
1923
|
-
}, requestOptions)
|
|
1924
|
-
|
|
1925
|
-
|
|
1993
|
+
}, requestOptions);
|
|
1994
|
+
} else {
|
|
1995
|
+
[, geoVerification, profileResult] = await Promise.all([
|
|
1996
|
+
Promise.resolve(void 0),
|
|
1997
|
+
this.geoClient.verifyIP({
|
|
1998
|
+
ip_address: request.ipAddress,
|
|
1999
|
+
user_id: request.customerId,
|
|
2000
|
+
event_type: "transaction",
|
|
2001
|
+
device_fingerprint: request.deviceFingerprint
|
|
2002
|
+
}, requestOptions),
|
|
2003
|
+
this.riskClient.getProfile(request.customerId, requestOptions).catch(() => null)
|
|
2004
|
+
]);
|
|
2005
|
+
}
|
|
1926
2006
|
const geoBlocked = !geoVerification.is_compliant || geoVerification.is_blocked || !!cipherTextResult?.risk?.is_blocked || cipherTextResult?.valid === false || geoVerification.gps_required && !cipherTextResult;
|
|
1927
2007
|
if (geoBlocked && !profileResult) {
|
|
1928
2008
|
return {
|
|
@@ -1941,6 +2021,9 @@ var ComplianceClient = class {
|
|
|
1941
2021
|
cipherTextValidation: cipherTextResult
|
|
1942
2022
|
};
|
|
1943
2023
|
}
|
|
2024
|
+
if (!profileResult) {
|
|
2025
|
+
throw new ComplianceError("Customer profile not found", request.customerId);
|
|
2026
|
+
}
|
|
1944
2027
|
const profile = profileResult;
|
|
1945
2028
|
const transactionRisk = this.calculateTransactionRisk(
|
|
1946
2029
|
request.amount,
|
|
@@ -1983,22 +2066,31 @@ var ComplianceClient = class {
|
|
|
1983
2066
|
async verifyEvent(request, requestOptions) {
|
|
1984
2067
|
const startTime = Date.now();
|
|
1985
2068
|
this.validateEventRequest(request);
|
|
1986
|
-
|
|
1987
|
-
|
|
2069
|
+
let cipherTextResult;
|
|
2070
|
+
let geoVerification;
|
|
2071
|
+
if (request.cipherText) {
|
|
2072
|
+
cipherTextResult = await this.executeCipherTextValidation(
|
|
1988
2073
|
request.cipherText,
|
|
1989
2074
|
request.customerId,
|
|
1990
2075
|
request.eventType,
|
|
1991
2076
|
request.ipAddress,
|
|
1992
2077
|
void 0,
|
|
1993
2078
|
requestOptions
|
|
1994
|
-
)
|
|
1995
|
-
this.geoClient.verifyIP({
|
|
2079
|
+
);
|
|
2080
|
+
geoVerification = (cipherTextResult && this.buildLocationFromCipherText(cipherTextResult, request.ipAddress)) ?? await this.geoClient.verifyIP({
|
|
1996
2081
|
ip_address: request.ipAddress,
|
|
1997
2082
|
user_id: request.customerId,
|
|
1998
2083
|
event_type: request.eventType,
|
|
1999
2084
|
device_fingerprint: request.deviceFingerprint
|
|
2000
|
-
}, requestOptions)
|
|
2001
|
-
|
|
2085
|
+
}, requestOptions);
|
|
2086
|
+
} else {
|
|
2087
|
+
geoVerification = await this.geoClient.verifyIP({
|
|
2088
|
+
ip_address: request.ipAddress,
|
|
2089
|
+
user_id: request.customerId,
|
|
2090
|
+
event_type: request.eventType,
|
|
2091
|
+
device_fingerprint: request.deviceFingerprint
|
|
2092
|
+
}, requestOptions);
|
|
2093
|
+
}
|
|
2002
2094
|
if (this.config.autoCreateProfiles) {
|
|
2003
2095
|
try {
|
|
2004
2096
|
const profile = await this.riskClient.getProfile(request.customerId, requestOptions);
|
|
@@ -2012,7 +2104,7 @@ var ComplianceClient = class {
|
|
|
2012
2104
|
}
|
|
2013
2105
|
}
|
|
2014
2106
|
const cipherTextBlocked = cipherTextResult ? !cipherTextResult.valid || cipherTextResult.risk?.is_blocked === true : false;
|
|
2015
|
-
const blockReasons = [...geoVerification.risk_reasons];
|
|
2107
|
+
const blockReasons = [...geoVerification.risk_reasons ?? []];
|
|
2016
2108
|
if (cipherTextResult) {
|
|
2017
2109
|
if (!cipherTextResult.valid) {
|
|
2018
2110
|
blockReasons.push("ciphertext_validation_failed");
|
|
@@ -2081,6 +2173,44 @@ var ComplianceClient = class {
|
|
|
2081
2173
|
return void 0;
|
|
2082
2174
|
}
|
|
2083
2175
|
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Build a LocationVerification from a ValidateCipherTextResponse.
|
|
2178
|
+
* The validate-ciphertext endpoint now returns the full geo-verification data
|
|
2179
|
+
* (is_compliant, jurisdiction, geofence_evaluation, record_id, gps_required),
|
|
2180
|
+
* so a separate verifyIP call is unnecessary.
|
|
2181
|
+
*/
|
|
2182
|
+
buildLocationFromCipherText(ct, ipAddress) {
|
|
2183
|
+
const loc = ct.location;
|
|
2184
|
+
const risk = ct.risk;
|
|
2185
|
+
if (!risk) return null;
|
|
2186
|
+
return {
|
|
2187
|
+
ip_address: ct.ip_address || ipAddress,
|
|
2188
|
+
location: {
|
|
2189
|
+
country: loc?.country ?? "",
|
|
2190
|
+
country_iso: loc?.country_iso ?? "",
|
|
2191
|
+
city: loc?.city ?? "",
|
|
2192
|
+
region: loc?.region ?? "",
|
|
2193
|
+
postal_code: "",
|
|
2194
|
+
latitude: loc?.latitude ?? 0,
|
|
2195
|
+
longitude: loc?.longitude ?? 0,
|
|
2196
|
+
timezone: "",
|
|
2197
|
+
is_vpn: risk.is_vpn,
|
|
2198
|
+
is_proxy: risk.is_proxy,
|
|
2199
|
+
is_tor: risk.is_tor,
|
|
2200
|
+
is_hosting: risk.is_hosting ?? false,
|
|
2201
|
+
is_anonymizer: risk.is_vpn || risk.is_proxy || risk.is_tor
|
|
2202
|
+
},
|
|
2203
|
+
is_compliant: ct.is_compliant ?? !risk.is_blocked,
|
|
2204
|
+
is_blocked: risk.is_blocked,
|
|
2205
|
+
risk_level: risk.level,
|
|
2206
|
+
risk_score: risk.score,
|
|
2207
|
+
risk_reasons: risk.is_blocked && risk.block_reasons ? risk.block_reasons : risk.factors ?? [],
|
|
2208
|
+
jurisdiction: ct.jurisdiction,
|
|
2209
|
+
geofence_evaluation: ct.geofence_evaluation,
|
|
2210
|
+
record_id: ct.record_id ?? "",
|
|
2211
|
+
gps_required: ct.gps_required
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2084
2214
|
calculateTransactionRisk(amount, currency, geoVerification, profile, cipherTextResult) {
|
|
2085
2215
|
if (!this._currencyRatesCustomized && !this._currencyRatesWarned) {
|
|
2086
2216
|
this._currencyRatesWarned = true;
|
|
@@ -2151,13 +2281,15 @@ var ComplianceClient = class {
|
|
|
2151
2281
|
getBlockReasons(geoVerification, profile, cipherTextResult) {
|
|
2152
2282
|
const reasons = [];
|
|
2153
2283
|
if (geoVerification.is_blocked) {
|
|
2154
|
-
reasons.push(...geoVerification.risk_reasons);
|
|
2155
|
-
}
|
|
2156
|
-
if (profile.customer_status === "suspended") {
|
|
2157
|
-
reasons.push("account_suspended");
|
|
2284
|
+
reasons.push(...geoVerification.risk_reasons ?? []);
|
|
2158
2285
|
}
|
|
2159
|
-
if (profile
|
|
2160
|
-
|
|
2286
|
+
if (profile) {
|
|
2287
|
+
if (profile.customer_status === "suspended") {
|
|
2288
|
+
reasons.push("account_suspended");
|
|
2289
|
+
}
|
|
2290
|
+
if (profile.has_sanctions) {
|
|
2291
|
+
reasons.push("sanctions_match");
|
|
2292
|
+
}
|
|
2161
2293
|
}
|
|
2162
2294
|
if (cipherTextResult) {
|
|
2163
2295
|
if (!cipherTextResult.valid) {
|
|
@@ -3015,235 +3147,93 @@ var TaxClient = class extends BaseClient {
|
|
|
3015
3147
|
};
|
|
3016
3148
|
super(baseConfig);
|
|
3017
3149
|
}
|
|
3018
|
-
//
|
|
3019
|
-
// Tax
|
|
3020
|
-
//
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
*
|
|
3026
|
-
* @example
|
|
3027
|
-
* ```typescript
|
|
3028
|
-
* const config = await client.getTaxConfig();
|
|
3029
|
-
* console.log(`Tax enabled: ${config.tax_enabled}`);
|
|
3030
|
-
* ```
|
|
3031
|
-
*/
|
|
3032
|
-
async getTaxConfig() {
|
|
3033
|
-
const res = await this.request("/api/v1/tax/config");
|
|
3034
|
-
return res.tax_config;
|
|
3150
|
+
// ==========================================================================
|
|
3151
|
+
// P1 — Customer Tax Profile (core compliance flow)
|
|
3152
|
+
// ==========================================================================
|
|
3153
|
+
async getCustomerTaxProfileRecord(customerID) {
|
|
3154
|
+
return this.request(
|
|
3155
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}`
|
|
3156
|
+
);
|
|
3035
3157
|
}
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
*
|
|
3042
|
-
* @example
|
|
3043
|
-
* ```typescript
|
|
3044
|
-
* // Enable tax
|
|
3045
|
-
* const config = await client.updateTaxConfig({ tax_enabled: true });
|
|
3046
|
-
*
|
|
3047
|
-
* // Disable tax
|
|
3048
|
-
* const config = await client.updateTaxConfig({ tax_enabled: false });
|
|
3049
|
-
* ```
|
|
3050
|
-
*/
|
|
3051
|
-
async updateTaxConfig(request) {
|
|
3052
|
-
const res = await this.request("/api/v1/tax/config", {
|
|
3053
|
-
method: "PUT",
|
|
3054
|
-
body: JSON.stringify({ tax_config: request })
|
|
3055
|
-
});
|
|
3056
|
-
return res.tax_config;
|
|
3158
|
+
async requestTaxForm(customerID) {
|
|
3159
|
+
return this.request(
|
|
3160
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}/request-form`,
|
|
3161
|
+
{ method: "POST" }
|
|
3162
|
+
);
|
|
3057
3163
|
}
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
* Get solicitation triggers for the tenant
|
|
3063
|
-
*
|
|
3064
|
-
* @returns List of solicitation triggers with their enabled state
|
|
3065
|
-
*
|
|
3066
|
-
* @example
|
|
3067
|
-
* ```typescript
|
|
3068
|
-
* const triggers = await client.getSolicitationTriggers();
|
|
3069
|
-
* triggers.forEach(t => console.log(`${t.label}: ${t.enabled}`));
|
|
3070
|
-
* ```
|
|
3071
|
-
*/
|
|
3072
|
-
async getSolicitationTriggers() {
|
|
3073
|
-
const res = await this.request(
|
|
3074
|
-
"/api/v1/tax/solicitation/config"
|
|
3164
|
+
async checkTINStatus(customerID) {
|
|
3165
|
+
return this.requestWithRetry(
|
|
3166
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}/check-tin`,
|
|
3167
|
+
{ method: "POST" }
|
|
3075
3168
|
);
|
|
3076
|
-
return res.solicitation_triggers;
|
|
3077
3169
|
}
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
* @param triggers - Array of triggers with updated enabled/threshold values
|
|
3082
|
-
* @returns Updated triggers
|
|
3083
|
-
*
|
|
3084
|
-
* @example
|
|
3085
|
-
* ```typescript
|
|
3086
|
-
* const triggers = await client.updateSolicitationTriggers([
|
|
3087
|
-
* { type: 'first_withdrawal', enabled: true, label: 'First Withdrawal', description: '...' },
|
|
3088
|
-
* { type: 'threshold_based', enabled: true, label: 'Threshold', description: '...', threshold_amount: 600 },
|
|
3089
|
-
* ]);
|
|
3090
|
-
* ```
|
|
3091
|
-
*/
|
|
3092
|
-
async updateSolicitationTriggers(triggers) {
|
|
3093
|
-
const res = await this.request(
|
|
3094
|
-
"/api/v1/tax/solicitation/config",
|
|
3170
|
+
async reRequestTaxForm(customerID, input) {
|
|
3171
|
+
return this.request(
|
|
3172
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}/re-request-form`,
|
|
3095
3173
|
{
|
|
3096
|
-
method: "
|
|
3097
|
-
body: JSON.stringify(
|
|
3174
|
+
method: "POST",
|
|
3175
|
+
body: JSON.stringify(input)
|
|
3098
3176
|
}
|
|
3099
3177
|
);
|
|
3100
|
-
return res.solicitation_triggers;
|
|
3101
|
-
}
|
|
3102
|
-
// ============================================================================
|
|
3103
|
-
// Reminder Configuration
|
|
3104
|
-
// ============================================================================
|
|
3105
|
-
/**
|
|
3106
|
-
* Get the reminder configuration for the tenant
|
|
3107
|
-
*
|
|
3108
|
-
* @returns Reminder config (enabled, max_reminders, frequency_days)
|
|
3109
|
-
*
|
|
3110
|
-
* @example
|
|
3111
|
-
* ```typescript
|
|
3112
|
-
* const config = await client.getReminderConfig();
|
|
3113
|
-
* console.log(`Reminders enabled: ${config.enabled}, every ${config.frequency_days} days`);
|
|
3114
|
-
* ```
|
|
3115
|
-
*/
|
|
3116
|
-
async getReminderConfig() {
|
|
3117
|
-
const res = await this.request(
|
|
3118
|
-
"/api/v1/tax/solicitation/reminder-config"
|
|
3119
|
-
);
|
|
3120
|
-
return res.reminder_config;
|
|
3121
3178
|
}
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
* @param config - Reminder configuration to set
|
|
3126
|
-
* @returns Updated reminder config
|
|
3127
|
-
*
|
|
3128
|
-
* @example
|
|
3129
|
-
* ```typescript
|
|
3130
|
-
* const updated = await client.updateReminderConfig({
|
|
3131
|
-
* enabled: true,
|
|
3132
|
-
* max_reminders: 3,
|
|
3133
|
-
* frequency_days: 7,
|
|
3134
|
-
* });
|
|
3135
|
-
* ```
|
|
3136
|
-
*/
|
|
3137
|
-
async updateReminderConfig(config) {
|
|
3138
|
-
const res = await this.request(
|
|
3139
|
-
"/api/v1/tax/solicitation/reminder-config",
|
|
3179
|
+
async enableBackupWithholding(customerID, input) {
|
|
3180
|
+
return this.request(
|
|
3181
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}/enable-withholding`,
|
|
3140
3182
|
{
|
|
3141
|
-
method: "
|
|
3142
|
-
body: JSON.stringify(
|
|
3183
|
+
method: "POST",
|
|
3184
|
+
body: JSON.stringify(input)
|
|
3143
3185
|
}
|
|
3144
3186
|
);
|
|
3145
|
-
return res.reminder_config;
|
|
3146
3187
|
}
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
* @param filters - Optional filters (customer_id, form_type, form_status, etc.)
|
|
3154
|
-
* @returns Paginated list of tax forms
|
|
3155
|
-
*
|
|
3156
|
-
* @example
|
|
3157
|
-
* ```typescript
|
|
3158
|
-
* const result = await client.listTaxForms({ form_type: 'W-9', form_status: 'Pending' });
|
|
3159
|
-
* console.log(`Found ${result.total} forms`);
|
|
3160
|
-
* ```
|
|
3161
|
-
*/
|
|
3162
|
-
async listTaxForms(filters) {
|
|
3163
|
-
const params = {};
|
|
3164
|
-
if (filters) {
|
|
3165
|
-
if (filters.customer_id) params.customer_id = filters.customer_id;
|
|
3166
|
-
if (filters.form_type) params.form_type = filters.form_type;
|
|
3167
|
-
if (filters.form_status) params.form_status = filters.form_status;
|
|
3168
|
-
if (filters.tin_status) params.tin_status = filters.tin_status;
|
|
3169
|
-
if (filters.avalara_company_id) params.avalara_company_id = filters.avalara_company_id;
|
|
3170
|
-
if (filters.search) params.search = filters.search;
|
|
3171
|
-
if (filters.start_date) params.start_date = filters.start_date;
|
|
3172
|
-
if (filters.end_date) params.end_date = filters.end_date;
|
|
3173
|
-
if (filters.page) params.page = filters.page;
|
|
3174
|
-
if (filters.page_size) params.limit = filters.page_size;
|
|
3175
|
-
}
|
|
3176
|
-
return this.request(`/api/v1/tax/forms${this.buildQueryString(params)}`);
|
|
3177
|
-
}
|
|
3178
|
-
/**
|
|
3179
|
-
* Get a tax form by ID
|
|
3180
|
-
*
|
|
3181
|
-
* @param formId - Tax form UUID
|
|
3182
|
-
* @returns Tax form details
|
|
3183
|
-
*/
|
|
3184
|
-
async getTaxForm(formId) {
|
|
3185
|
-
return this.request(`/api/v1/tax/forms/${formId}`);
|
|
3186
|
-
}
|
|
3187
|
-
/**
|
|
3188
|
-
* Get lifecycle events for a tax form
|
|
3189
|
-
*
|
|
3190
|
-
* @param formId - Tax form UUID
|
|
3191
|
-
* @returns List of lifecycle events
|
|
3192
|
-
*/
|
|
3193
|
-
async getTaxFormLifecycleEvents(formId) {
|
|
3194
|
-
const res = await this.request(
|
|
3195
|
-
`/api/v1/tax/forms/${formId}/lifecycle`
|
|
3188
|
+
async downloadTaxForm(customerID, requestOptions) {
|
|
3189
|
+
return this.request(
|
|
3190
|
+
`/api/v1/tax/customer-tax-profiles/${customerID}/download-form`,
|
|
3191
|
+
{ method: "GET" },
|
|
3192
|
+
void 0,
|
|
3193
|
+
{ ...requestOptions, responseType: "arraybuffer" }
|
|
3196
3194
|
);
|
|
3197
|
-
return res.lifecycle_events;
|
|
3198
3195
|
}
|
|
3199
|
-
//
|
|
3200
|
-
//
|
|
3201
|
-
//
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
* @param customerID - Customer ID
|
|
3206
|
-
* @returns Customer tax profile with all forms and events
|
|
3207
|
-
*
|
|
3208
|
-
* @example
|
|
3209
|
-
* ```typescript
|
|
3210
|
-
* const profile = await client.getCustomerTaxProfile('cust_123');
|
|
3211
|
-
* console.log(`Customer has ${profile.tax_forms.length} tax forms`);
|
|
3212
|
-
* ```
|
|
3213
|
-
*/
|
|
3214
|
-
async getCustomerTaxProfile(customerID) {
|
|
3215
|
-
return this.request(`/api/v1/tax/profile/${customerID}`);
|
|
3196
|
+
// ==========================================================================
|
|
3197
|
+
// P2 — Tenant Tax Rules
|
|
3198
|
+
// ==========================================================================
|
|
3199
|
+
async getTaxRules() {
|
|
3200
|
+
const res = await this.request("/api/v1/tax/rules");
|
|
3201
|
+
return res.rules;
|
|
3216
3202
|
}
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
* @returns Paginated list of tax companies
|
|
3226
|
-
*/
|
|
3227
|
-
async listTaxCompanies(page, pageSize) {
|
|
3203
|
+
async updateTaxRules(input) {
|
|
3204
|
+
const res = await this.request("/api/v1/tax/rules", {
|
|
3205
|
+
method: "PUT",
|
|
3206
|
+
body: JSON.stringify({ rules: input })
|
|
3207
|
+
});
|
|
3208
|
+
return res.version;
|
|
3209
|
+
}
|
|
3210
|
+
async getComplianceStats(filters) {
|
|
3228
3211
|
const params = {};
|
|
3229
|
-
if (
|
|
3230
|
-
if (
|
|
3212
|
+
if (filters?.time_range) params.time_range = filters.time_range;
|
|
3213
|
+
if (filters?.from_date) params.from_date = filters.from_date;
|
|
3214
|
+
if (filters?.to_date) params.to_date = filters.to_date;
|
|
3231
3215
|
return this.request(
|
|
3232
|
-
`/api/v1/tax/
|
|
3216
|
+
`/api/v1/tax/tenant/w-form-tenant-stats${this.buildQueryString(params)}`
|
|
3233
3217
|
);
|
|
3234
3218
|
}
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
return
|
|
3219
|
+
// ==========================================================================
|
|
3220
|
+
// P3 — Global Tax Rule & Treaty Countries
|
|
3221
|
+
// ==========================================================================
|
|
3222
|
+
async getCurrentGlobalTaxRule() {
|
|
3223
|
+
const res = await this.request(
|
|
3224
|
+
"/api/v1/tm/tenant/global-tax-rules/current"
|
|
3225
|
+
);
|
|
3226
|
+
return res.data;
|
|
3227
|
+
}
|
|
3228
|
+
async listTreatyCountries() {
|
|
3229
|
+
return this.request("/api/v1/tax/treaty-countries");
|
|
3230
|
+
}
|
|
3231
|
+
async getTreatyCountry(code) {
|
|
3232
|
+
const res = await this.request(
|
|
3233
|
+
`/api/v1/tax/treaty-countries/${encodeURIComponent(code)}`
|
|
3234
|
+
);
|
|
3235
|
+
return res.treaty_country;
|
|
3243
3236
|
}
|
|
3244
|
-
// ============================================================================
|
|
3245
|
-
// Utility Methods (inherited from BaseClient: healthCheck, updateConfig, getConfig, buildQueryString)
|
|
3246
|
-
// ============================================================================
|
|
3247
3237
|
};
|
|
3248
3238
|
|
|
3249
3239
|
// src/transaction/client.ts
|