@easyflow/javascript-sdk 2.1.8 → 2.1.10

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.
Files changed (94) hide show
  1. package/README.md +87 -7
  2. package/dist/index.d.ts +421 -0
  3. package/package.json +19 -6
  4. package/.babelrc +0 -5
  5. package/.github/workflows/deploy-sdk-cf.yml +0 -49
  6. package/.github/workflows/release-sdk-cdn.yml +0 -144
  7. package/.github/workflows/release-sdk.yml +0 -112
  8. package/.prettierrc +0 -6
  9. package/CDN-DEPLOYMENT.md +0 -175
  10. package/DEMO.md +0 -258
  11. package/DEPLOYMENT.md +0 -224
  12. package/INTEGRATION-GUIDE.md +0 -521
  13. package/coverage/base.css +0 -224
  14. package/coverage/block-navigation.js +0 -87
  15. package/coverage/easyflow-javascript-sdk/index.html +0 -116
  16. package/coverage/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  17. package/coverage/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  18. package/coverage/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  19. package/coverage/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  20. package/coverage/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  21. package/coverage/easyflow-javascript-sdk/libs/index.html +0 -266
  22. package/coverage/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  23. package/coverage/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  24. package/coverage/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  25. package/coverage/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  26. package/coverage/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  27. package/coverage/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  28. package/coverage/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +0 -131
  31. package/coverage/lcov-report/base.css +0 -224
  32. package/coverage/lcov-report/block-navigation.js +0 -87
  33. package/coverage/lcov-report/easyflow-javascript-sdk/index.html +0 -116
  34. package/coverage/lcov-report/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  35. package/coverage/lcov-report/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  36. package/coverage/lcov-report/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  37. package/coverage/lcov-report/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  38. package/coverage/lcov-report/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  39. package/coverage/lcov-report/easyflow-javascript-sdk/libs/index.html +0 -266
  40. package/coverage/lcov-report/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  41. package/coverage/lcov-report/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  42. package/coverage/lcov-report/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  43. package/coverage/lcov-report/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  44. package/coverage/lcov-report/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  45. package/coverage/lcov-report/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  46. package/coverage/lcov-report/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  47. package/coverage/lcov-report/favicon.png +0 -0
  48. package/coverage/lcov-report/index.html +0 -131
  49. package/coverage/lcov-report/prettify.css +0 -1
  50. package/coverage/lcov-report/prettify.js +0 -2
  51. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  52. package/coverage/lcov-report/sorter.js +0 -196
  53. package/coverage/lcov.info +0 -1429
  54. package/coverage/prettify.css +0 -1
  55. package/coverage/prettify.js +0 -2
  56. package/coverage/sort-arrow-sprite.png +0 -0
  57. package/coverage/sorter.js +0 -196
  58. package/dist/435.easyflow-sdk.min.js +0 -1
  59. package/dist/easyflow-sdk.min.js +0 -1
  60. package/dist/easyflow-sdk.min.js.LICENSE.txt +0 -1
  61. package/dist/index.html +0 -756
  62. package/docs/index.html +0 -775
  63. package/examples/lovable-integration.html +0 -410
  64. package/index.html +0 -981
  65. package/jest.config.js +0 -37
  66. package/jsdoc.json +0 -42
  67. package/libs/auto-integration.mjs +0 -333
  68. package/libs/constants.mjs +0 -61
  69. package/libs/constants.spec.js +0 -198
  70. package/libs/errors.mjs +0 -62
  71. package/libs/errors.spec.js +0 -178
  72. package/libs/exception-handler.mjs +0 -21
  73. package/libs/exception-handler.spec.js +0 -237
  74. package/libs/fingerprint.mjs +0 -270
  75. package/libs/http.mjs +0 -163
  76. package/libs/http.spec.js +0 -427
  77. package/libs/integration-wrapper.mjs +0 -285
  78. package/libs/logger.mjs +0 -161
  79. package/libs/logger.spec.js +0 -389
  80. package/libs/sanitizer.mjs +0 -340
  81. package/libs/sanitizer.spec.js +0 -583
  82. package/libs/security.mjs +0 -217
  83. package/libs/types.mjs +0 -141
  84. package/libs/utils.mjs +0 -368
  85. package/libs/utils.spec.js +0 -231
  86. package/libs/validator.mjs +0 -952
  87. package/libs/validator.spec.js +0 -615
  88. package/mocks/offer.mock.js +0 -77
  89. package/scripts/publish-npm.sh +0 -82
  90. package/sdk.mjs +0 -945
  91. package/sdk.spec.js +0 -796
  92. package/test-setup.cjs +0 -211
  93. package/test.html +0 -154
  94. 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 }