@easyflow/javascript-sdk 2.1.7 → 2.1.9
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 +294 -713
- package/dist/index.d.ts +421 -0
- package/package.json +19 -6
- package/.babelrc +0 -5
- package/.github/workflows/deploy-sdk-cf.yml +0 -49
- package/.github/workflows/release-sdk-cdn.yml +0 -144
- package/.github/workflows/release-sdk.yml +0 -112
- package/.prettierrc +0 -6
- package/CDN-DEPLOYMENT.md +0 -175
- package/DEMO.md +0 -258
- package/DEPLOYMENT.md +0 -224
- package/INTEGRATION-GUIDE.md +0 -521
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/easyflow-javascript-sdk/index.html +0 -116
- package/coverage/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
- package/coverage/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
- package/coverage/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
- package/coverage/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
- package/coverage/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
- package/coverage/easyflow-javascript-sdk/libs/index.html +0 -266
- package/coverage/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
- package/coverage/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
- package/coverage/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
- package/coverage/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
- package/coverage/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
- package/coverage/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
- package/coverage/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -131
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/easyflow-javascript-sdk/index.html +0 -116
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/index.html +0 -266
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
- package/coverage/lcov-report/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
- package/coverage/lcov-report/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -131
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -1429
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/dist/435.easyflow-sdk.min.js +0 -1
- package/dist/easyflow-sdk.min.js +0 -1
- package/dist/easyflow-sdk.min.js.LICENSE.txt +0 -1
- package/dist/index.html +0 -756
- package/docs/index.html +0 -775
- package/examples/lovable-integration.html +0 -410
- package/index.html +0 -981
- package/jest.config.js +0 -37
- package/jsdoc.json +0 -42
- package/libs/auto-integration.mjs +0 -333
- package/libs/constants.mjs +0 -61
- package/libs/constants.spec.js +0 -198
- package/libs/errors.mjs +0 -62
- package/libs/errors.spec.js +0 -178
- package/libs/exception-handler.mjs +0 -21
- package/libs/exception-handler.spec.js +0 -237
- package/libs/fingerprint.mjs +0 -270
- package/libs/http.mjs +0 -163
- package/libs/http.spec.js +0 -427
- package/libs/integration-wrapper.mjs +0 -285
- package/libs/logger.mjs +0 -161
- package/libs/logger.spec.js +0 -389
- package/libs/sanitizer.mjs +0 -340
- package/libs/sanitizer.spec.js +0 -583
- package/libs/security.mjs +0 -217
- package/libs/types.mjs +0 -141
- package/libs/utils.mjs +0 -368
- package/libs/utils.spec.js +0 -231
- package/libs/validator.mjs +0 -952
- package/libs/validator.spec.js +0 -615
- package/mocks/offer.mock.js +0 -77
- package/scripts/publish-npm.sh +0 -82
- package/sdk.mjs +0 -945
- package/sdk.spec.js +0 -796
- package/test-setup.cjs +0 -211
- package/test.html +0 -154
- package/webpack.config.cjs +0 -41
package/sdk.mjs
DELETED
|
@@ -1,945 +0,0 @@
|
|
|
1
|
-
import { callSecureApi } from './libs/http.mjs'
|
|
2
|
-
import { sanitizeOrderData, Sanitizer } from './libs/sanitizer.mjs'
|
|
3
|
-
import { Validator } from './libs/validator.mjs'
|
|
4
|
-
import { RateLimiter, SECURITY_CONFIG } from './libs/security.mjs'
|
|
5
|
-
import { SecureLogger } from './libs/logger.mjs'
|
|
6
|
-
import { PAYMENT_METHODS, TARGETS } from './libs/constants.mjs'
|
|
7
|
-
import {
|
|
8
|
-
findPaymentByMethod,
|
|
9
|
-
isValidBankBilletPayment,
|
|
10
|
-
isValidPixPayment,
|
|
11
|
-
mapCreditCardIfNeeded,
|
|
12
|
-
} from './libs/utils.mjs'
|
|
13
|
-
import { throwsError } from './libs/exception-handler.mjs'
|
|
14
|
-
import { NetworkError, SecurityError, ValidationError } from './libs/errors.mjs'
|
|
15
|
-
import { EasyflowIntegrationWrapper, initializeEasyflow, } from './libs/integration-wrapper.mjs'
|
|
16
|
-
|
|
17
|
-
let SDK_VERSION = '2.1.4'
|
|
18
|
-
try {
|
|
19
|
-
const versionModule = await import('./version.mjs')
|
|
20
|
-
SDK_VERSION = versionModule.SDK_VERSION
|
|
21
|
-
} catch (error) {
|
|
22
|
-
try {
|
|
23
|
-
if (
|
|
24
|
-
typeof process !== 'undefined' &&
|
|
25
|
-
process.versions &&
|
|
26
|
-
process.versions.node
|
|
27
|
-
) {
|
|
28
|
-
const fs = await import('fs')
|
|
29
|
-
const path = await import('path')
|
|
30
|
-
const packagePath = path.join(process.cwd(), 'package.json')
|
|
31
|
-
const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'))
|
|
32
|
-
SDK_VERSION = packageData.version
|
|
33
|
-
}
|
|
34
|
-
} catch (fallbackError) {
|
|
35
|
-
console.warn(
|
|
36
|
-
'Could not determine SDK version, using default:',
|
|
37
|
-
SDK_VERSION
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* EasyflowSDK - Main SDK class for Easyflow payment processing
|
|
44
|
-
*
|
|
45
|
-
* This class provides a secure interface for interacting with the Easyflow payment API.
|
|
46
|
-
* It includes built-in security features, rate limiting, and comprehensive error handling.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```javascript
|
|
50
|
-
* const sdk = new EasyflowSDK({ businessId: 'your-business-id' });
|
|
51
|
-
* const offer = await sdk.getOffer('offer-id');
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* @class EasyflowSDK
|
|
55
|
-
* @since 1.0.0
|
|
56
|
-
*/
|
|
57
|
-
class EasyflowSDK {
|
|
58
|
-
/**
|
|
59
|
-
* SDK version - dynamically set from package.json
|
|
60
|
-
* @type {string}
|
|
61
|
-
* @static
|
|
62
|
-
* @readonly
|
|
63
|
-
*/
|
|
64
|
-
static version = SDK_VERSION
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Event listeners storage
|
|
68
|
-
* @type {Object}
|
|
69
|
-
* @private
|
|
70
|
-
*/
|
|
71
|
-
#eventListeners = {}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Creates a new EasyflowSDK instance
|
|
75
|
-
*
|
|
76
|
-
* @param {string|Object} config - Configuration object or business ID string
|
|
77
|
-
* @param {string} config.businessId - Your Easyflow business identifier (required)
|
|
78
|
-
* @param {Object} [config.additionalOptions] - Additional configuration options
|
|
79
|
-
*
|
|
80
|
-
* @throws {SecurityError} When businessId is missing or invalid
|
|
81
|
-
* @throws {ValidationError} When configuration is invalid
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```javascript
|
|
85
|
-
* // Using string configuration
|
|
86
|
-
* const sdk = new EasyflowSDK('your-business-id');
|
|
87
|
-
*
|
|
88
|
-
* // Using object configuration
|
|
89
|
-
* const sdk = new EasyflowSDK({
|
|
90
|
-
* businessId: 'your-business-id',
|
|
91
|
-
* additionalOptions: {}
|
|
92
|
-
* });
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
constructor(config) {
|
|
96
|
-
this.rateLimiter = new RateLimiter()
|
|
97
|
-
this.logger = new SecureLogger(
|
|
98
|
-
SECURITY_CONFIG.PRODUCTION_MODE ? 'error' : 'info'
|
|
99
|
-
)
|
|
100
|
-
if (typeof config === 'string') this.config = { businessId: config }
|
|
101
|
-
else this.config = { ...config }
|
|
102
|
-
if (!this.config.businessId)
|
|
103
|
-
throw new SecurityError('businessId is required')
|
|
104
|
-
|
|
105
|
-
Validator.validateBusinessId(this.config.businessId, 'businessId')
|
|
106
|
-
|
|
107
|
-
this.config.businessId = Sanitizer.sanitizeInput(this.config.businessId)
|
|
108
|
-
this.logger.info('EasyflowSDK initialized with security protections')
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Initialize Easyflow SDK for low-code/no-code platforms
|
|
113
|
-
* @param {Object} config - Configuration object
|
|
114
|
-
* @returns {EasyflowIntegrationWrapper} Integration wrapper instance
|
|
115
|
-
* @static
|
|
116
|
-
*/
|
|
117
|
-
static initializeForPlatform(config) {
|
|
118
|
-
return initializeEasyflow(config)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Create integration wrapper instance
|
|
123
|
-
* @param {Object} config - Configuration object
|
|
124
|
-
* @returns {EasyflowIntegrationWrapper} Integration wrapper instance
|
|
125
|
-
* @static
|
|
126
|
-
*/
|
|
127
|
-
static createWrapper(config) {
|
|
128
|
-
return new EasyflowIntegrationWrapper(config)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Add event listener
|
|
133
|
-
* @param {string} event - Event name
|
|
134
|
-
* @param {Function} callback - Callback function
|
|
135
|
-
*/
|
|
136
|
-
on(event, callback) {
|
|
137
|
-
if (!this.#eventListeners[event]) {
|
|
138
|
-
this.#eventListeners[event] = []
|
|
139
|
-
}
|
|
140
|
-
this.#eventListeners[event].push(callback)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Remove event listener
|
|
145
|
-
* @param {string} event - Event name
|
|
146
|
-
* @param {Function} callback - Callback function
|
|
147
|
-
*/
|
|
148
|
-
off(event, callback) {
|
|
149
|
-
if (this.#eventListeners[event]) {
|
|
150
|
-
const index = this.#eventListeners[event].indexOf(callback)
|
|
151
|
-
if (index > -1) {
|
|
152
|
-
this.#eventListeners[event].splice(index, 1)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Emit event to all listeners
|
|
159
|
-
* @param {string} event - Event name
|
|
160
|
-
* @param {*} data - Event data
|
|
161
|
-
* @private
|
|
162
|
-
*/
|
|
163
|
-
#emit(event, data) {
|
|
164
|
-
if (this.#eventListeners[event]) {
|
|
165
|
-
this.#eventListeners[event].forEach((callback) => {
|
|
166
|
-
try {
|
|
167
|
-
callback(data)
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.error(
|
|
170
|
-
`Error in event listener for ${event}:`,
|
|
171
|
-
error
|
|
172
|
-
)
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Retrieves offer information by offer ID
|
|
180
|
-
*
|
|
181
|
-
* @param {string} offerId - The unique identifier of the offer
|
|
182
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
183
|
-
* @returns {Promise<Object>} Promise that resolves to the offer data
|
|
184
|
-
*
|
|
185
|
-
* @throws {ValidationError} When offerId is invalid or missing
|
|
186
|
-
* @throws {NetworkError} When API request fails
|
|
187
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
188
|
-
*
|
|
189
|
-
* @example
|
|
190
|
-
* ```javascript
|
|
191
|
-
* const offer = await sdk.getOffer('550e8400-e29b-41d4-a716-446655440000');
|
|
192
|
-
* console.log(offer.name, offer.price);
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
async getOffer(offerId, headers = {}) {
|
|
196
|
-
await this.rateLimiter.checkLimit('getOffer')
|
|
197
|
-
const sanitizedOfferId = Sanitizer.sanitizeInput(offerId)
|
|
198
|
-
if (!sanitizedOfferId) throw new ValidationError('Invalid offer ID')
|
|
199
|
-
|
|
200
|
-
Validator.validateOfferId(sanitizedOfferId, 'offerId')
|
|
201
|
-
|
|
202
|
-
try {
|
|
203
|
-
const result = await callSecureApi(
|
|
204
|
-
TARGETS.GET_OFFER,
|
|
205
|
-
{ offerId: sanitizedOfferId },
|
|
206
|
-
headers
|
|
207
|
-
)
|
|
208
|
-
if (result.error) throwsError(new NetworkError(result.error))
|
|
209
|
-
if (!result.data)
|
|
210
|
-
throwsError(new ValidationError('Offer not found'))
|
|
211
|
-
return result.data
|
|
212
|
-
} catch (error) {
|
|
213
|
-
this.logger.error('Failed to get offer', {
|
|
214
|
-
offerId: sanitizedOfferId,
|
|
215
|
-
error: error.message,
|
|
216
|
-
})
|
|
217
|
-
throwsError(error)
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Places an order using an existing offer
|
|
223
|
-
*
|
|
224
|
-
* @param {string} offerId - The unique identifier of the offer
|
|
225
|
-
* @param {Object} data - Order data including payment information
|
|
226
|
-
* @param {Object} data.buyer - Buyer information
|
|
227
|
-
* @param {Array<Object>} data.payments - Array of payment methods
|
|
228
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
229
|
-
* @returns {Promise<string>} Promise that resolves to the order ID
|
|
230
|
-
*
|
|
231
|
-
* @throws {ValidationError} When offerId is invalid or order data is invalid
|
|
232
|
-
* @throws {NetworkError} When API request fails
|
|
233
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
234
|
-
*
|
|
235
|
-
* @example
|
|
236
|
-
* ```javascript
|
|
237
|
-
* const orderId = await sdk.placeOrder('550e8400-e29b-41d4-a716-446655440000', {
|
|
238
|
-
* customer: {
|
|
239
|
-
* name: 'John Doe',
|
|
240
|
-
* email: 'john@example.com',
|
|
241
|
-
* document: {
|
|
242
|
-
* type: 'CPF',
|
|
243
|
-
* number: '12345678901'
|
|
244
|
-
* },
|
|
245
|
-
* phone: {
|
|
246
|
-
* areaCode: '+55',
|
|
247
|
-
* ddd: '11',
|
|
248
|
-
* number: '999999999',
|
|
249
|
-
* isMobile: true
|
|
250
|
-
* },
|
|
251
|
-
* address: {
|
|
252
|
-
* zipCode: '01234567',
|
|
253
|
-
* street: 'Rua Example',
|
|
254
|
-
* number: '123',
|
|
255
|
-
* neighborhood: 'Centro',
|
|
256
|
-
* city: 'São Paulo',
|
|
257
|
-
* state: 'SP'
|
|
258
|
-
* },
|
|
259
|
-
* creditCard: { // card data },
|
|
260
|
-
* pix: { // pix data },
|
|
261
|
-
* bankBillet: { // bank billet data }
|
|
262
|
-
* }
|
|
263
|
-
* });
|
|
264
|
-
* console.log('Order created:', orderId);
|
|
265
|
-
* ```
|
|
266
|
-
*/
|
|
267
|
-
async placeOrder(offerId, data, headers = {}) {
|
|
268
|
-
await this.rateLimiter.checkLimit('placeOrder')
|
|
269
|
-
const sanitizedOfferId = Sanitizer.sanitizeInput(offerId)
|
|
270
|
-
if (!sanitizedOfferId) throw new ValidationError('Invalid offer ID')
|
|
271
|
-
|
|
272
|
-
Validator.validateOfferId(sanitizedOfferId, 'offerId')
|
|
273
|
-
Validator.validateOrderData(data)
|
|
274
|
-
if (data.buyer) Validator.validateCustomer(data.buyer, 'data.buyer')
|
|
275
|
-
|
|
276
|
-
const sanitizedData = sanitizeOrderData(data)
|
|
277
|
-
try {
|
|
278
|
-
const orderData = mapCreditCardIfNeeded(sanitizedData)
|
|
279
|
-
const offer = await this.getOffer(sanitizedOfferId, headers)
|
|
280
|
-
if (!offer?.items?.[0]?.id)
|
|
281
|
-
throwsError(
|
|
282
|
-
new ValidationError('Invalid offer: no items found')
|
|
283
|
-
)
|
|
284
|
-
const placeOrderPayload = {
|
|
285
|
-
...orderData,
|
|
286
|
-
businessId: this.config.businessId,
|
|
287
|
-
offerItems: [{ quantity: 1, offerItemId: offer.items[0].id }],
|
|
288
|
-
}
|
|
289
|
-
const response = await callSecureApi(
|
|
290
|
-
TARGETS.PLACE_ORDER,
|
|
291
|
-
placeOrderPayload,
|
|
292
|
-
headers
|
|
293
|
-
)
|
|
294
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
295
|
-
if (!response.data?.orderId)
|
|
296
|
-
throwsError(
|
|
297
|
-
new NetworkError('Invalid response: no order ID returned')
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
// Emit orderPlaced event
|
|
301
|
-
this.#emit('orderPlaced', {
|
|
302
|
-
orderId: response.data.orderId,
|
|
303
|
-
offerId: sanitizedOfferId,
|
|
304
|
-
data: orderData,
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
return response.data.orderId
|
|
308
|
-
} catch (error) {
|
|
309
|
-
this.logger.error('Failed to place order', {
|
|
310
|
-
offerId: sanitizedOfferId,
|
|
311
|
-
error: error.message,
|
|
312
|
-
})
|
|
313
|
-
throwsError(error)
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Retrieves order information by order ID
|
|
319
|
-
*
|
|
320
|
-
* @param {string} orderId - The unique identifier of the order
|
|
321
|
-
* @param headers
|
|
322
|
-
* @returns {Promise<Object>} Promise that resolves to the order data
|
|
323
|
-
*
|
|
324
|
-
* @throws {NetworkError} When API request fails
|
|
325
|
-
*
|
|
326
|
-
* @example
|
|
327
|
-
* ```javascript
|
|
328
|
-
* const order = await sdk.getOrder('550e8400-e29b-41d4-a716-446655440000');
|
|
329
|
-
* console.log(order.status, order.total);
|
|
330
|
-
* ```
|
|
331
|
-
*/
|
|
332
|
-
async getOrder(orderId, headers = {}) {
|
|
333
|
-
Validator.validateOrderId(orderId, 'orderId')
|
|
334
|
-
const response = await callSecureApi(
|
|
335
|
-
TARGETS.GET_ORDER,
|
|
336
|
-
{ orderId },
|
|
337
|
-
headers
|
|
338
|
-
)
|
|
339
|
-
return (response && response.data) || null
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Retrieves bank billet information for an order
|
|
344
|
-
*
|
|
345
|
-
* @param {string} orderId - The unique identifier of the order
|
|
346
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
347
|
-
* @returns {Promise<Object|null>} Promise that resolves to bank billet data or null if not found
|
|
348
|
-
*
|
|
349
|
-
* @throws {ValidationError} When orderId is invalid
|
|
350
|
-
* @throws {NetworkError} When API request fails
|
|
351
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
352
|
-
*
|
|
353
|
-
* @example
|
|
354
|
-
* ```javascript
|
|
355
|
-
* const bankBillet = await sdk.getBankBillet('550e8400-e29b-41d4-a716-446655440000');
|
|
356
|
-
* console.log(bankBillet.code, bankBillet.expirationDate);
|
|
357
|
-
* ```
|
|
358
|
-
*/
|
|
359
|
-
async getBankBillet(orderId, headers = {}) {
|
|
360
|
-
await this.rateLimiter.checkLimit('getBankBillet')
|
|
361
|
-
const sanitizedOrderId = Sanitizer.sanitizeInput(orderId)
|
|
362
|
-
if (!sanitizedOrderId) throw new ValidationError('Invalid order ID')
|
|
363
|
-
try {
|
|
364
|
-
const order = await this.getOrder(sanitizedOrderId, headers)
|
|
365
|
-
const bankBilletPayment = findPaymentByMethod(
|
|
366
|
-
order,
|
|
367
|
-
PAYMENT_METHODS.BANK_BILLET,
|
|
368
|
-
isValidBankBilletPayment
|
|
369
|
-
)
|
|
370
|
-
return bankBilletPayment?.bankBillet || null
|
|
371
|
-
} catch (error) {
|
|
372
|
-
this.logger.error('Failed to get bank billet', {
|
|
373
|
-
orderId: sanitizedOrderId,
|
|
374
|
-
error: error.message,
|
|
375
|
-
})
|
|
376
|
-
throwsError(error)
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Processes a direct charge without using an offer
|
|
382
|
-
*
|
|
383
|
-
* @param {Object} data - Charge data including items and payment information
|
|
384
|
-
* @param {Object} data.buyer - Buyer information
|
|
385
|
-
* @param {Array<Object>} data.items - Array of items to charge
|
|
386
|
-
* @param {Array<Object>} data.payments - Array of payment methods
|
|
387
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
388
|
-
* @returns {Promise<string>} Promise that resolves to the order ID
|
|
389
|
-
*
|
|
390
|
-
* @throws {ValidationError} When charge data is invalid
|
|
391
|
-
* @throws {NetworkError} When API request fails
|
|
392
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
393
|
-
*
|
|
394
|
-
* @example
|
|
395
|
-
* ```javascript
|
|
396
|
-
* const orderId = await sdk.charge({
|
|
397
|
-
* items: [{ name: 'Product', price: 1000 }],
|
|
398
|
-
* payments: [{
|
|
399
|
-
* method: 'pix',
|
|
400
|
-
* numberInstallments: 1
|
|
401
|
-
* }]
|
|
402
|
-
* });
|
|
403
|
-
* ```
|
|
404
|
-
*/
|
|
405
|
-
async charge(data, headers = {}) {
|
|
406
|
-
await this.rateLimiter.checkLimit('charge')
|
|
407
|
-
Validator.validateOrderData(data)
|
|
408
|
-
Validator.validateChargeItemsData(data.items)
|
|
409
|
-
const sanitizedData = sanitizeOrderData(data)
|
|
410
|
-
try {
|
|
411
|
-
const payload = mapCreditCardIfNeeded(sanitizedData)
|
|
412
|
-
const response = await callSecureApi(
|
|
413
|
-
TARGETS.CHARGE,
|
|
414
|
-
{
|
|
415
|
-
...payload,
|
|
416
|
-
businessId: this.config.businessId,
|
|
417
|
-
},
|
|
418
|
-
headers
|
|
419
|
-
)
|
|
420
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
421
|
-
if (!response.data?.orderId)
|
|
422
|
-
throwsError(
|
|
423
|
-
new NetworkError('Invalid response: no order ID returned')
|
|
424
|
-
)
|
|
425
|
-
|
|
426
|
-
// Emit paymentProcessed event
|
|
427
|
-
this.#emit('paymentProcessed', {
|
|
428
|
-
orderId: response.data.orderId,
|
|
429
|
-
data: payload,
|
|
430
|
-
})
|
|
431
|
-
|
|
432
|
-
return response.data.orderId
|
|
433
|
-
} catch (error) {
|
|
434
|
-
this.logger.error('Failed to process charge', {
|
|
435
|
-
error: error.message,
|
|
436
|
-
})
|
|
437
|
-
throwsError(error)
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Encrypts credit card data for secure transmission
|
|
443
|
-
*
|
|
444
|
-
* @param {Object} creditCard - Credit card data to encrypt
|
|
445
|
-
* @param {string} creditCard.cardNumber - Card number (13-19 digits)
|
|
446
|
-
* @param {string} creditCard.holderName - Cardholder name
|
|
447
|
-
* @param {string} creditCard.month - Expiration month (1-12)
|
|
448
|
-
* @param {string} creditCard.year - Expiration year (4 digits)
|
|
449
|
-
* @param {string} creditCard.cvv - Security code (3-4 digits)
|
|
450
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
451
|
-
* @returns {Promise<string>} Promise that resolves to the encrypted token
|
|
452
|
-
*
|
|
453
|
-
* @throws {ValidationError} When credit card data is invalid
|
|
454
|
-
* @throws {NetworkError} When API request fails
|
|
455
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
456
|
-
*
|
|
457
|
-
* @example
|
|
458
|
-
* ```javascript
|
|
459
|
-
* const token = await sdk.encrypt({
|
|
460
|
-
* cardNumber: '4111111111111111',
|
|
461
|
-
* holderName: 'John Doe',
|
|
462
|
-
* month: '12',
|
|
463
|
-
* year: '2025',
|
|
464
|
-
* cvv: '123'
|
|
465
|
-
* });
|
|
466
|
-
* ```
|
|
467
|
-
*/
|
|
468
|
-
async encrypt(creditCard, headers = {}) {
|
|
469
|
-
await this.rateLimiter.checkLimit('encrypt')
|
|
470
|
-
Validator.validateCreditCardData(creditCard)
|
|
471
|
-
const sanitizedCard = Sanitizer.sanitizeCreditCard(creditCard)
|
|
472
|
-
try {
|
|
473
|
-
const response = await callSecureApi(
|
|
474
|
-
TARGETS.ENCRYPT,
|
|
475
|
-
sanitizedCard,
|
|
476
|
-
headers
|
|
477
|
-
)
|
|
478
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
479
|
-
if (!response.data?.token)
|
|
480
|
-
throwsError(
|
|
481
|
-
new NetworkError('Invalid response: no token returned')
|
|
482
|
-
)
|
|
483
|
-
return response.data.token
|
|
484
|
-
} catch (error) {
|
|
485
|
-
this.logger.error('Failed to encrypt credit card', {
|
|
486
|
-
error: error.message,
|
|
487
|
-
})
|
|
488
|
-
throw error
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
/**
|
|
493
|
-
* Retrieves PIX payment information for an order
|
|
494
|
-
*
|
|
495
|
-
* @param {string} orderId - The unique identifier of the order
|
|
496
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
497
|
-
* @returns {Promise<Object|null>} Promise that resolves to PIX data or null if not found
|
|
498
|
-
*
|
|
499
|
-
* @throws {ValidationError} When orderId is invalid
|
|
500
|
-
* @throws {NetworkError} When API request fails
|
|
501
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
502
|
-
*
|
|
503
|
-
* @example
|
|
504
|
-
* ```javascript
|
|
505
|
-
* const pix = await sdk.getPix('550e8400-e29b-41d4-a716-446655440000');
|
|
506
|
-
* console.log(pix.qrCode, pix.expirationDate);
|
|
507
|
-
* ```
|
|
508
|
-
*/
|
|
509
|
-
async getPix(orderId, headers = {}) {
|
|
510
|
-
await this.rateLimiter.checkLimit('getPix')
|
|
511
|
-
const sanitizedOrderId = Sanitizer.sanitizeInput(orderId)
|
|
512
|
-
if (!sanitizedOrderId) throw new ValidationError('Invalid order ID')
|
|
513
|
-
try {
|
|
514
|
-
const order = await this.getOrder(sanitizedOrderId, headers)
|
|
515
|
-
const pixPayment = findPaymentByMethod(
|
|
516
|
-
order,
|
|
517
|
-
PAYMENT_METHODS.PIX,
|
|
518
|
-
isValidPixPayment
|
|
519
|
-
)
|
|
520
|
-
return pixPayment?.pix || null
|
|
521
|
-
} catch (error) {
|
|
522
|
-
this.logger.error('Failed to get PIX data', {
|
|
523
|
-
orderId: sanitizedOrderId,
|
|
524
|
-
error: error.message,
|
|
525
|
-
})
|
|
526
|
-
throw error
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* Creates a new customer
|
|
532
|
-
*
|
|
533
|
-
* @param {Object} customer - Customer data to create
|
|
534
|
-
* @param {string} customer.name - Customer full name
|
|
535
|
-
* @param {string} customer.email - Customer email address
|
|
536
|
-
* @param {Object} customer.document - Customer legal document
|
|
537
|
-
* @param {string} customer.document.type - Document type ('CPF' or 'CNPJ')
|
|
538
|
-
* @param {string} customer.document.number - Document number
|
|
539
|
-
* @param {Object} customer.phone - Customer phone information
|
|
540
|
-
* @param {string} customer.phone.areaCode - Country area code
|
|
541
|
-
* @param {string} customer.phone.ddd - Area code
|
|
542
|
-
* @param {string} customer.phone.number - Phone number
|
|
543
|
-
* @param {boolean} customer.phone.isMobile - Whether the phone is mobile
|
|
544
|
-
* @param {Object} [customer.address] - Customer billing address
|
|
545
|
-
* @param {Object} [customer.deliveryAddress] - Customer delivery address
|
|
546
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
547
|
-
* @returns {Promise<Object>} Promise that resolves to the created customer data
|
|
548
|
-
*
|
|
549
|
-
* @throws {ValidationError} When customer data is invalid
|
|
550
|
-
* @throws {NetworkError} When API request fails
|
|
551
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
552
|
-
*
|
|
553
|
-
* @example
|
|
554
|
-
* ```javascript
|
|
555
|
-
* const customer = await sdk.createCustomer({
|
|
556
|
-
* name: 'John Doe',
|
|
557
|
-
* email: 'john@example.com',
|
|
558
|
-
* document: { type: 'CPF', number: '12345678901' },
|
|
559
|
-
* phone: {
|
|
560
|
-
* areaCode: '+55',
|
|
561
|
-
* ddd: '11',
|
|
562
|
-
* number: '999999999',
|
|
563
|
-
* isMobile: true
|
|
564
|
-
* }
|
|
565
|
-
* });
|
|
566
|
-
* ```
|
|
567
|
-
*/
|
|
568
|
-
async createCustomer(customer, headers = {}) {
|
|
569
|
-
await this.rateLimiter.checkLimit('createCustomer')
|
|
570
|
-
if (!customer || typeof customer !== 'object') {
|
|
571
|
-
throwsError(new ValidationError('Customer data is required'))
|
|
572
|
-
}
|
|
573
|
-
Validator.validateCustomer(customer, 'customer')
|
|
574
|
-
const sanitizedCustomer = Sanitizer.sanitizeInput(customer)
|
|
575
|
-
const payload = {
|
|
576
|
-
...sanitizedCustomer,
|
|
577
|
-
businessId: this.config.businessId,
|
|
578
|
-
}
|
|
579
|
-
try {
|
|
580
|
-
const response = await callSecureApi(
|
|
581
|
-
TARGETS.CREATE_CUSTOMER,
|
|
582
|
-
payload,
|
|
583
|
-
headers
|
|
584
|
-
)
|
|
585
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
586
|
-
if (!response.data)
|
|
587
|
-
throwsError(
|
|
588
|
-
new NetworkError(
|
|
589
|
-
'Invalid response: no customer data returned'
|
|
590
|
-
)
|
|
591
|
-
)
|
|
592
|
-
this.#emit('customerCreated', response.data)
|
|
593
|
-
return response.data && response.data.customer
|
|
594
|
-
} catch (error) {
|
|
595
|
-
this.logger.error('Failed to create customer', {
|
|
596
|
-
error: error.message,
|
|
597
|
-
})
|
|
598
|
-
throwsError(error)
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
/**
|
|
603
|
-
* Retrieves customer information by ID
|
|
604
|
-
*
|
|
605
|
-
* @param {string} id - Customer unique identifier
|
|
606
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
607
|
-
* @returns {Promise<Object>} Promise that resolves to the customer data
|
|
608
|
-
*
|
|
609
|
-
* @throws {ValidationError} When customer ID is invalid
|
|
610
|
-
* @throws {NetworkError} When API request fails
|
|
611
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
612
|
-
*
|
|
613
|
-
* @example
|
|
614
|
-
* ```javascript
|
|
615
|
-
* const customer = await sdk.getCustomer('550e8400-e29b-41d4-a716-446655440000');
|
|
616
|
-
* console.log(customer.name, customer.email);
|
|
617
|
-
* ```
|
|
618
|
-
*/
|
|
619
|
-
async getCustomer(id, headers = {}) {
|
|
620
|
-
await this.rateLimiter.checkLimit('getCustomer')
|
|
621
|
-
const sanitizedId = Sanitizer.sanitizeInput(id)
|
|
622
|
-
if (!sanitizedId)
|
|
623
|
-
throwsError(new ValidationError('Invalid customer ID'))
|
|
624
|
-
Validator.validateCustomerId(sanitizedId, 'customerId')
|
|
625
|
-
try {
|
|
626
|
-
const response = await callSecureApi(
|
|
627
|
-
TARGETS.GET_CUSTOMER,
|
|
628
|
-
{ customerId: sanitizedId, businessId: this.config.businessId },
|
|
629
|
-
headers
|
|
630
|
-
)
|
|
631
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
632
|
-
if (!response.data) {
|
|
633
|
-
throwsError(new ValidationError('Customer not found'))
|
|
634
|
-
}
|
|
635
|
-
return response.data && response.data.customer
|
|
636
|
-
} catch (error) {
|
|
637
|
-
this.logger.error('Failed to get customer', {
|
|
638
|
-
customerId: sanitizedId,
|
|
639
|
-
error: error.message,
|
|
640
|
-
})
|
|
641
|
-
throwsError(error)
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/**
|
|
646
|
-
* Updates an existing customer
|
|
647
|
-
*
|
|
648
|
-
* @param {string} id - Customer unique identifier
|
|
649
|
-
* @param {Object} customer - Customer data to update
|
|
650
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
651
|
-
* @returns {Promise<Object>} Promise that resolves to update confirmation
|
|
652
|
-
*
|
|
653
|
-
* @throws {ValidationError} When customer ID is invalid
|
|
654
|
-
* @throws {NetworkError} When API request fails
|
|
655
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
656
|
-
*
|
|
657
|
-
* @example
|
|
658
|
-
* ```javascript
|
|
659
|
-
* const result = await sdk.updateCustomer('550e8400-e29b-41d4-a716-446655440000', {
|
|
660
|
-
* name: 'John Updated',
|
|
661
|
-
* email: 'john.updated@example.com'
|
|
662
|
-
* });
|
|
663
|
-
* ```
|
|
664
|
-
*/
|
|
665
|
-
async updateCustomer(id, customer, headers = {}) {
|
|
666
|
-
await this.rateLimiter.checkLimit('updateCustomer')
|
|
667
|
-
const sanitizedId = Sanitizer.sanitizeInput(id)
|
|
668
|
-
if (!sanitizedId)
|
|
669
|
-
throwsError(new ValidationError('Invalid customer ID'))
|
|
670
|
-
if (!customer || typeof customer !== 'object')
|
|
671
|
-
throwsError(new ValidationError('Customer update data is required'))
|
|
672
|
-
|
|
673
|
-
const sanitizedCustomer = Sanitizer.sanitizeInput(customer)
|
|
674
|
-
const payload = {
|
|
675
|
-
customerId: sanitizedId,
|
|
676
|
-
businessId: this.config.businessId,
|
|
677
|
-
...sanitizedCustomer,
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
try {
|
|
681
|
-
const response = await callSecureApi(
|
|
682
|
-
TARGETS.UPDATE_CUSTOMER,
|
|
683
|
-
payload,
|
|
684
|
-
headers
|
|
685
|
-
)
|
|
686
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
687
|
-
if (!response.data) {
|
|
688
|
-
throwsError(
|
|
689
|
-
new NetworkError(
|
|
690
|
-
'Invalid response: no update confirmation returned'
|
|
691
|
-
)
|
|
692
|
-
)
|
|
693
|
-
}
|
|
694
|
-
return response.data
|
|
695
|
-
} catch (error) {
|
|
696
|
-
this.logger.error('Failed to update customer', {
|
|
697
|
-
customerId: sanitizedId,
|
|
698
|
-
error: error.message,
|
|
699
|
-
})
|
|
700
|
-
throwsError(error)
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
/**
|
|
705
|
-
* Adds a credit card to a customer
|
|
706
|
-
*
|
|
707
|
-
* @param {string} customerId - Customer unique identifier
|
|
708
|
-
* @param {string} creditCardToken - Encrypted credit card token
|
|
709
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
710
|
-
* @returns {Promise<Object>} Promise that resolves to credit card creation confirmation
|
|
711
|
-
*
|
|
712
|
-
* @throws {ValidationError} When customer ID or credit card token is invalid
|
|
713
|
-
* @throws {NetworkError} When API request fails
|
|
714
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
715
|
-
*
|
|
716
|
-
* @example
|
|
717
|
-
* ```javascript
|
|
718
|
-
* const result = await sdk.addCreditCard('550e8400-e29b-41d4-a716-446655440000', 'encrypted-token-456');
|
|
719
|
-
* console.log('Credit card ID:', result.creditCardId);
|
|
720
|
-
* ```
|
|
721
|
-
*/
|
|
722
|
-
async addCreditCard(customerId, creditCardToken, headers = {}) {
|
|
723
|
-
await this.rateLimiter.checkLimit('addCreditCard')
|
|
724
|
-
const sanitizedCustomerId = Sanitizer.sanitizeInput(customerId)
|
|
725
|
-
const sanitizedToken = Sanitizer.sanitizeInput(creditCardToken)
|
|
726
|
-
|
|
727
|
-
if (!sanitizedCustomerId)
|
|
728
|
-
throwsError(new ValidationError('Invalid customer ID'))
|
|
729
|
-
if (!sanitizedToken)
|
|
730
|
-
throwsError(new ValidationError('Invalid credit card token'))
|
|
731
|
-
Validator.validateCustomerId(sanitizedCustomerId, 'customerId')
|
|
732
|
-
|
|
733
|
-
Validator.validateCreditCardToken(sanitizedToken, 'creditCardToken')
|
|
734
|
-
|
|
735
|
-
const payload = {
|
|
736
|
-
customerId: sanitizedCustomerId,
|
|
737
|
-
businessId: this.config.businessId,
|
|
738
|
-
creditCardToken: sanitizedToken,
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
try {
|
|
742
|
-
const response = await callSecureApi(
|
|
743
|
-
TARGETS.ADD_CREDIT_CARD,
|
|
744
|
-
payload,
|
|
745
|
-
headers
|
|
746
|
-
)
|
|
747
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
748
|
-
if (!response.data?.creditCardId) {
|
|
749
|
-
throwsError(
|
|
750
|
-
new NetworkError(
|
|
751
|
-
'Invalid response: no credit card ID returned'
|
|
752
|
-
)
|
|
753
|
-
)
|
|
754
|
-
}
|
|
755
|
-
return response.data && response.data.creditCard
|
|
756
|
-
} catch (error) {
|
|
757
|
-
this.logger.error('Failed to add credit card', {
|
|
758
|
-
customerId: sanitizedCustomerId,
|
|
759
|
-
error: error.message,
|
|
760
|
-
})
|
|
761
|
-
throwsError(error)
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Removes a credit card from a customer
|
|
767
|
-
*
|
|
768
|
-
* @param {string} customerId - Customer unique identifier
|
|
769
|
-
* @param {string} creditCardId - Credit card unique identifier
|
|
770
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
771
|
-
* @returns {Promise<Object>} Promise that resolves to removal confirmation
|
|
772
|
-
*
|
|
773
|
-
* @throws {ValidationError} When customer ID or credit card ID is invalid
|
|
774
|
-
* @throws {NetworkError} When API request fails
|
|
775
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
776
|
-
*
|
|
777
|
-
* @example
|
|
778
|
-
* ```javascript
|
|
779
|
-
* const result = await sdk.removeCreditCard('550e8400-e29b-41d4-a716-446655440000', 'card-456');
|
|
780
|
-
* ```
|
|
781
|
-
*/
|
|
782
|
-
async removeCreditCard(customerId, creditCardId, headers = {}) {
|
|
783
|
-
await this.rateLimiter.checkLimit('removeCreditCard')
|
|
784
|
-
const sanitizedCustomerId = Sanitizer.sanitizeInput(customerId)
|
|
785
|
-
const sanitizedCardId = Sanitizer.sanitizeInput(creditCardId)
|
|
786
|
-
|
|
787
|
-
if (!sanitizedCustomerId)
|
|
788
|
-
throwsError(new ValidationError('Invalid customer ID'))
|
|
789
|
-
if (!sanitizedCardId)
|
|
790
|
-
throwsError(new ValidationError('Invalid credit card ID'))
|
|
791
|
-
|
|
792
|
-
const payload = {
|
|
793
|
-
customerId: sanitizedCustomerId,
|
|
794
|
-
businessId: this.config.businessId,
|
|
795
|
-
creditCardId: sanitizedCardId,
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
try {
|
|
799
|
-
const response = await callSecureApi(
|
|
800
|
-
TARGETS.REMOVE_CREDIT_CARD,
|
|
801
|
-
payload,
|
|
802
|
-
headers
|
|
803
|
-
)
|
|
804
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
805
|
-
if (!response.data) {
|
|
806
|
-
throwsError(
|
|
807
|
-
new NetworkError(
|
|
808
|
-
'Invalid response: no removal confirmation returned'
|
|
809
|
-
)
|
|
810
|
-
)
|
|
811
|
-
}
|
|
812
|
-
return response.data
|
|
813
|
-
} catch (error) {
|
|
814
|
-
this.logger.error('Failed to remove credit card', {
|
|
815
|
-
customerId: sanitizedCustomerId,
|
|
816
|
-
creditCardId: sanitizedCardId,
|
|
817
|
-
error: error.message,
|
|
818
|
-
})
|
|
819
|
-
throwsError(error)
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
/**
|
|
824
|
-
* Retrieves credit card information by ID
|
|
825
|
-
*
|
|
826
|
-
* @param {string} customerId - Customer unique identifier
|
|
827
|
-
* @param {string} creditCardId - Credit card unique identifier
|
|
828
|
-
* @param {Object} [headers={}] - Additional HTTP headers to include in the request
|
|
829
|
-
* @returns {Promise<Object>} Promise that resolves to the credit card data
|
|
830
|
-
*
|
|
831
|
-
* @throws {ValidationError} When customer ID or credit card ID is invalid
|
|
832
|
-
* @throws {NetworkError} When API request fails
|
|
833
|
-
* @throws {SecurityError} When rate limit is exceeded
|
|
834
|
-
*
|
|
835
|
-
* @example
|
|
836
|
-
* ```javascript
|
|
837
|
-
* const creditCard = await sdk.getCreditCard('550e8400-e29b-41d4-a716-446655440000', 'card-456');
|
|
838
|
-
* console.log(creditCard.brand, creditCard.last4Numbers);
|
|
839
|
-
* ```
|
|
840
|
-
*/
|
|
841
|
-
async getCreditCard(customerId, creditCardId, headers = {}) {
|
|
842
|
-
await this.rateLimiter.checkLimit('getCreditCard')
|
|
843
|
-
const sanitizedCustomerId = Sanitizer.sanitizeInput(customerId)
|
|
844
|
-
const sanitizedCardId = Sanitizer.sanitizeInput(creditCardId)
|
|
845
|
-
|
|
846
|
-
if (!sanitizedCustomerId)
|
|
847
|
-
throwsError(new ValidationError('Invalid customer ID'))
|
|
848
|
-
if (!sanitizedCardId)
|
|
849
|
-
throwsError(new ValidationError('Invalid credit card ID'))
|
|
850
|
-
|
|
851
|
-
const payload = {
|
|
852
|
-
customerId: sanitizedCustomerId,
|
|
853
|
-
businessId: this.config.businessId,
|
|
854
|
-
creditCardId: sanitizedCardId,
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
try {
|
|
858
|
-
const response = await callSecureApi(
|
|
859
|
-
TARGETS.GET_CREDIT_CARD,
|
|
860
|
-
payload,
|
|
861
|
-
headers
|
|
862
|
-
)
|
|
863
|
-
if (response.error) throwsError(new NetworkError(response.error))
|
|
864
|
-
if (!response.data) {
|
|
865
|
-
throwsError(new ValidationError('Credit card not found'))
|
|
866
|
-
}
|
|
867
|
-
return response.data && response.data.creditCard
|
|
868
|
-
} catch (error) {
|
|
869
|
-
this.logger.error('Failed to get credit card', {
|
|
870
|
-
customerId: sanitizedCustomerId,
|
|
871
|
-
creditCardId: sanitizedCardId,
|
|
872
|
-
error: error.message,
|
|
873
|
-
})
|
|
874
|
-
throwsError(error)
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
if (typeof window !== 'undefined') {
|
|
880
|
-
try {
|
|
881
|
-
if (SECURITY_CONFIG.PRODUCTION_MODE) {
|
|
882
|
-
if (
|
|
883
|
-
window.outerHeight - window.innerHeight > 200 ||
|
|
884
|
-
window.outerWidth - window.innerWidth > 200
|
|
885
|
-
) {
|
|
886
|
-
throwsError(new SecurityError('Debugging detected'))
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
// Expose the SDK class
|
|
891
|
-
window.EasyflowSDK = EasyflowSDK
|
|
892
|
-
|
|
893
|
-
// Create a global instance with event methods for low-code platforms
|
|
894
|
-
const globalSDK = new EasyflowSDK({ businessId: 'placeholder' })
|
|
895
|
-
|
|
896
|
-
// Expose global methods for low-code platforms
|
|
897
|
-
window.easyflowSDK = {
|
|
898
|
-
// Event methods
|
|
899
|
-
on: (event, callback) => globalSDK.on(event, callback),
|
|
900
|
-
off: (event, callback) => globalSDK.off(event, callback),
|
|
901
|
-
|
|
902
|
-
// Customer methods
|
|
903
|
-
createCustomer: (data) => globalSDK.createCustomer(data),
|
|
904
|
-
getCustomer: (id) => globalSDK.getCustomer(id),
|
|
905
|
-
updateCustomer: (id, data) => globalSDK.updateCustomer(id, data),
|
|
906
|
-
|
|
907
|
-
// Payment methods
|
|
908
|
-
placeOrder: (offerId, data) => globalSDK.placeOrder(offerId, data),
|
|
909
|
-
charge: (data) => globalSDK.charge(data),
|
|
910
|
-
|
|
911
|
-
// Validation methods
|
|
912
|
-
validate: {
|
|
913
|
-
email: (email) => Validator.validateEmail(email),
|
|
914
|
-
cpf: (cpf) => Validator.validateCPF(cpf),
|
|
915
|
-
cnpj: (cnpj) => Validator.validateCNPJ(cnpj),
|
|
916
|
-
phone: (phone) => Validator.validatePhone(phone),
|
|
917
|
-
address: (address) => Validator.validateAddress(address),
|
|
918
|
-
},
|
|
919
|
-
|
|
920
|
-
// Utility methods
|
|
921
|
-
encrypt: (creditCard) => globalSDK.encrypt(creditCard),
|
|
922
|
-
getOffer: (offerId) => globalSDK.getOffer(offerId),
|
|
923
|
-
getOrder: (orderId) => globalSDK.getOrder(orderId),
|
|
924
|
-
getPix: (orderId) => globalSDK.getPix(orderId),
|
|
925
|
-
getBankBillet: (orderId) => globalSDK.getBankBillet(orderId),
|
|
926
|
-
|
|
927
|
-
// Credit card methods
|
|
928
|
-
addCreditCard: (customerId, token) =>
|
|
929
|
-
globalSDK.addCreditCard(customerId, token),
|
|
930
|
-
removeCreditCard: (customerId, cardId) =>
|
|
931
|
-
globalSDK.removeCreditCard(customerId, cardId),
|
|
932
|
-
getCreditCard: (customerId, cardId) =>
|
|
933
|
-
globalSDK.getCreditCard(customerId, cardId),
|
|
934
|
-
|
|
935
|
-
// Version info
|
|
936
|
-
version: EasyflowSDK.version,
|
|
937
|
-
PAYMENT_METHODS,
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
console.log('Easyflow SDK exposto globalmente como "easyflowSDK"')
|
|
941
|
-
} catch (error) {
|
|
942
|
-
console.error('Security violation detected:', error.message)
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
export { EasyflowSDK, PAYMENT_METHODS }
|