@yosle/tropipayjs 0.2.3 → 0.3.0

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 (47) hide show
  1. package/README.md +69 -9
  2. package/index.d.ts +358 -76
  3. package/index.js +421 -342
  4. package/index.js.map +1 -0
  5. package/package.json +10 -2
  6. package/.nvmrc +0 -1
  7. package/.vscode/launch.json +0 -18
  8. package/SECURITY.md +0 -43
  9. package/api/TropipayAPI.d.ts +0 -133
  10. package/config/TropipayConfig.d.ts +0 -2
  11. package/constants/TropipayConstants.d.ts +0 -2
  12. package/depositAccount/depositAccounts.d.ts +0 -36
  13. package/docs/readme.md +0 -3
  14. package/globals.d.ts +0 -75
  15. package/hooks/TropipayHooks.d.ts +0 -38
  16. package/interfaces/countries/index.d.ts +0 -1
  17. package/interfaces/depositaccounts/index.d.ts +0 -68
  18. package/interfaces/index.d.ts +0 -176
  19. package/interfaces/mediation/index.d.ts +0 -22
  20. package/interfaces/paymentlink/index.d.ts +0 -87
  21. package/jest.config.js +0 -5
  22. package/mediationPaymentCard/MediationPaymentCard.d.ts +0 -17
  23. package/paymentcard/PaymentCard.d.ts +0 -37
  24. package/paymentcard/paymentcard.spec.d.ts +0 -1
  25. package/rollup.config.js +0 -23
  26. package/src/api/TropipayAPI.ts +0 -459
  27. package/src/config/TropipayConfig.ts +0 -2
  28. package/src/constants/TropipayConstants.ts +0 -2
  29. package/src/depositAccount/depositAccounts.ts +0 -139
  30. package/src/hooks/TropipayHooks.ts +0 -154
  31. package/src/index.ts +0 -29
  32. package/src/interfaces/depositaccounts/index.ts +0 -70
  33. package/src/interfaces/index.js +0 -2
  34. package/src/interfaces/index.ts +0 -212
  35. package/src/interfaces/mediation/index.ts +0 -23
  36. package/src/interfaces/paymentlink/index.d.ts +0 -36
  37. package/src/interfaces/paymentlink/index.js +0 -3
  38. package/src/interfaces/paymentlink/index.ts +0 -91
  39. package/src/mediationPaymentCard/MediationPaymentCard.ts +0 -42
  40. package/src/mocks/tropipay.ts +0 -0
  41. package/src/paymentcard/PaymentCard.ts +0 -123
  42. package/src/paymentcard/paymentcard.spec.ts +0 -79
  43. package/src/utils/TropipayUtils.ts +0 -126
  44. package/src/utils/errors.ts +0 -92
  45. package/tsconfig.json +0 -96
  46. package/utils/TropipayUtils.d.ts +0 -45
  47. package/utils/errors.d.ts +0 -16
package/index.js CHANGED
@@ -23,7 +23,17 @@ function _interopNamespaceDefault(e) {
23
23
 
24
24
  var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto);
25
25
 
26
+ const MAX_IMAGE_SIZE_MB = 2;
27
+ /**
28
+ * Base path for the Tropipay API. All SDK endpoints target API v3
29
+ * (v2 is deprecated).
30
+ */
31
+ const API_BASE = "/api/v3";
32
+
26
33
  function handleExceptions(error) {
34
+ // already mapped (e.g. thrown by login() inside the request interceptor)
35
+ if (error instanceof TropipayJSException)
36
+ return error;
27
37
  if (error instanceof axios.AxiosError) {
28
38
  if (error.response) {
29
39
  const axiosResponse = error.response;
@@ -79,7 +89,7 @@ class TropipayHooks {
79
89
  * you must select from the list of available events, otherwise
80
90
  * it will not produce an error but it will not be executed.
81
91
  * For get full list of available events see endpoint
82
- * GET /api/v2/hook/events.
92
+ * GET /api/v3/user/hooks/events.
83
93
  * @param target String representing the type of event supported.
84
94
  * It is currently available: 'web' (allows to receive information in a url),
85
95
  * 'email' (allows to receive information in an email address).
@@ -90,20 +100,11 @@ class TropipayHooks {
90
100
  * @returns
91
101
  */
92
102
  async subscribe({ eventType, target, value, }) {
93
- if (!Tropipay.accessToken) {
94
- await this.tropipay.login();
95
- }
96
103
  try {
97
- const hooks = await this.tropipay.request.post(`/api/v2/hooks`, {
104
+ const hooks = await this.tropipay.request.post(`${API_BASE}/user/hooks`, {
98
105
  event: eventType,
99
106
  target: target,
100
107
  value: value,
101
- }, {
102
- headers: {
103
- "Content-Type": "application/json",
104
- Authorization: `Bearer ${Tropipay.accessToken}`,
105
- Accept: "application/json",
106
- },
107
108
  });
108
109
  return hooks.data;
109
110
  }
@@ -119,17 +120,8 @@ class TropipayHooks {
119
120
  * @returns All subscribed hooks or empty Array if none exist.
120
121
  */
121
122
  async list(eventType) {
122
- if (!Tropipay.accessToken) {
123
- await this.tropipay.login();
124
- }
125
123
  try {
126
- const hooks = await this.tropipay.request.get(`/api/v2/hooks/${eventType || ""}`, {
127
- headers: {
128
- "Content-Type": "application/json",
129
- Authorization: `Bearer ${Tropipay.accessToken}`,
130
- Accept: "application/json",
131
- },
132
- });
124
+ const hooks = await this.tropipay.request.get(`${API_BASE}/user/hooks/${eventType || ""}`);
133
125
  return hooks.data;
134
126
  }
135
127
  catch (error) {
@@ -137,20 +129,11 @@ class TropipayHooks {
137
129
  }
138
130
  }
139
131
  async update(eventType, target, value) {
140
- if (!Tropipay.accessToken) {
141
- await this.tropipay.login();
142
- }
143
132
  try {
144
- const hooks = await this.tropipay.request.put(`/api/v2/hooks`, {
133
+ const hooks = await this.tropipay.request.put(`${API_BASE}/user/hooks`, {
145
134
  event: eventType,
146
135
  target: target,
147
136
  value: value,
148
- }, {
149
- headers: {
150
- "Content-Type": "application/json",
151
- Authorization: `Bearer ${Tropipay.accessToken}`,
152
- Accept: "application/json",
153
- },
154
137
  });
155
138
  return hooks.data;
156
139
  }
@@ -159,36 +142,17 @@ class TropipayHooks {
159
142
  }
160
143
  }
161
144
  async delete(eventType, target) {
162
- if (!Tropipay.accessToken) {
163
- await this.tropipay.login();
164
- }
165
145
  try {
166
- const hooks = await this.tropipay.request.delete(`/api/v2/hooks/${eventType}/${target}`, {
167
- headers: {
168
- "Content-Type": "application/json",
169
- Authorization: `Bearer ${Tropipay.accessToken}`,
170
- Accept: "application/json",
171
- },
172
- });
146
+ const hooks = await this.tropipay.request.delete(`${API_BASE}/user/hooks/${eventType}/${target}`);
173
147
  return hooks.data;
174
148
  }
175
149
  catch (error) {
176
- console.trace(error);
177
150
  throw handleExceptions(error);
178
151
  }
179
152
  }
180
153
  async events() {
181
- if (!Tropipay.accessToken) {
182
- await this.tropipay.login();
183
- }
184
154
  try {
185
- const hooks = await this.tropipay.request.get(`/api/v2/hooks/events`, {
186
- headers: {
187
- "Content-Type": "application/json",
188
- Authorization: `Bearer ${Tropipay.accessToken}`,
189
- Accept: "application/json",
190
- },
191
- });
155
+ const hooks = await this.tropipay.request.get(`${API_BASE}/user/hooks/events`);
192
156
  return hooks.data;
193
157
  }
194
158
  catch (error) {
@@ -204,22 +168,15 @@ class PaymentCard {
204
168
  }
205
169
  /**
206
170
  * Create a paymentLink with the specified options.
171
+ * Supports multi-account via the optional `accountId` field of the
172
+ * payload (defaults to the user's default account).
207
173
  * @param payload PaymentLinkPayload Object.
208
174
  * @returns Promise<PaymentLink> or throws an Exception.
209
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/b3A6ODgyNTM3OQ-create-a-new-pay-link-charge
175
+ * @see https://doc.tropipay.com/docs/api-reference/payment-cards
210
176
  */
211
177
  async create(payload) {
212
- if (!Tropipay.accessToken) {
213
- await this.tropipay.login();
214
- }
215
178
  try {
216
- const paylink = await this.tropipay.request.post("/api/v2/paymentcards", payload, {
217
- headers: {
218
- "Content-Type": "application/json",
219
- Authorization: `Bearer ${Tropipay.accessToken}`,
220
- Accept: "application/json",
221
- },
222
- });
179
+ const paylink = await this.tropipay.request.post(`${API_BASE}/paymentcards`, payload);
223
180
  return paylink.data;
224
181
  }
225
182
  catch (error) {
@@ -232,21 +189,12 @@ class PaymentCard {
232
189
  * @returns Array of paymentlinks
233
190
  */
234
191
  async list() {
235
- if (!Tropipay.accessToken) {
236
- await this.tropipay.login();
237
- }
238
192
  try {
239
- const paymentcards = await this.tropipay.request.get(`/api/v2/paymentcards`, {
240
- headers: {
241
- "Content-Type": "application/json",
242
- Authorization: `Bearer ${Tropipay.accessToken}`,
243
- Accept: "application/json",
244
- },
245
- });
193
+ const paymentcards = await this.tropipay.request.get(`${API_BASE}/paymentcards`);
246
194
  return paymentcards.data;
247
195
  }
248
196
  catch (error) {
249
- throw new Error(`Could not retrieve PaymenCards list`);
197
+ throw handleExceptions(error);
250
198
  }
251
199
  }
252
200
  /**
@@ -257,17 +205,25 @@ class PaymentCard {
257
205
  * @throws {Error} If an error occurs while retrieving the payment card.
258
206
  */
259
207
  async get(id) {
260
- if (!Tropipay.accessToken) {
261
- await this.tropipay.login();
208
+ try {
209
+ const paymentcard = await this.tropipay.request.get(`${API_BASE}/paymentcards/${id}`);
210
+ return paymentcard.data;
262
211
  }
212
+ catch (error) {
213
+ throw handleExceptions(error);
214
+ }
215
+ }
216
+ /**
217
+ * Updates a payment card. Send the card id in `cardId` plus the
218
+ * fields to modify.
219
+ *
220
+ * @param payload Object with `cardId` and the fields to update.
221
+ * @return {Promise<any>} A Promise that resolves to the updated payment card data.
222
+ * @throws {Error} If an error occurs while updating the payment card.
223
+ */
224
+ async update(payload) {
263
225
  try {
264
- const paymentcard = await this.tropipay.request.get(`/api/v2/paymentcards/${id}`, {
265
- headers: {
266
- "Content-Type": "application/json",
267
- Authorization: `Bearer ${Tropipay.accessToken}`,
268
- Accept: "application/json",
269
- },
270
- });
226
+ const paymentcard = await this.tropipay.request.put(`${API_BASE}/paymentcards/`, payload);
271
227
  return paymentcard.data;
272
228
  }
273
229
  catch (error) {
@@ -283,16 +239,8 @@ class PaymentCard {
283
239
  * @throws {Error} If an error occurs while deleting the payment card.
284
240
  */
285
241
  async delete(id) {
286
- if (!Tropipay.accessToken) {
287
- await this.tropipay.login();
288
- }
289
242
  try {
290
- const paymentcard = await this.tropipay.request.delete(`/api/v2/paymentcards/`, {
291
- headers: {
292
- "Content-Type": "application/json",
293
- Authorization: `Bearer ${Tropipay.accessToken}`,
294
- Accept: "application/json",
295
- },
243
+ const paymentcard = await this.tropipay.request.delete(`${API_BASE}/paymentcards/`, {
296
244
  data: {
297
245
  cardId: id,
298
246
  },
@@ -305,40 +253,6 @@ class PaymentCard {
305
253
  }
306
254
  }
307
255
 
308
- class MediationPaymentCard {
309
- tropipay;
310
- constructor(tropipayInstance) {
311
- this.tropipay = tropipayInstance;
312
- }
313
- /**
314
- * (ONLY FOR BUSINESS ACCOUNTS) Create a mediation paymentcard (an escrow payment link) with the specified options.
315
- * This allows a payment to be made to persons belonging or not to the TropiPay platform with the
316
- * particularity that the payment will be held in custody or retained until it is released with
317
- * the approval of the payer.
318
- * @param payload PaymentLinkPayload Object.
319
- * @returns Promise<PaymentLink> or throws an Exception.
320
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
321
- */
322
- async create(payload) {
323
- if (!Tropipay.accessToken) {
324
- await this.tropipay.login();
325
- }
326
- try {
327
- const paylink = await this.tropipay.request.post("/api/v2/paymentcards/mediation", payload, {
328
- headers: {
329
- "Content-Type": "application/json",
330
- Authorization: `Bearer ${Tropipay.accessToken}`,
331
- Accept: "application/json",
332
- },
333
- });
334
- return paylink.data;
335
- }
336
- catch (error) {
337
- throw handleExceptions(error);
338
- }
339
- }
340
- }
341
-
342
256
  class DepositAccounts {
343
257
  tropipay;
344
258
  constructor(tropipayInstance) {
@@ -349,44 +263,28 @@ class DepositAccounts {
349
263
  * @returns Array of DepositAccounts
350
264
  */
351
265
  async list() {
352
- if (!Tropipay.accessToken) {
353
- await this.tropipay.login();
354
- }
355
266
  try {
356
- const deposit = await this.tropipay.request.get(`/api/v2/deposit_accounts`, {
357
- headers: {
358
- "Content-Type": "application/json",
359
- Authorization: `Bearer ${Tropipay.accessToken}`,
360
- Accept: "application/json",
361
- },
362
- });
267
+ const deposit = await this.tropipay.request.get(`${API_BASE}/deposit_accounts`);
363
268
  return deposit.data;
364
269
  }
365
270
  catch (error) {
366
- return handleExceptions(error);
271
+ throw handleExceptions(error);
367
272
  }
368
273
  }
369
274
  /**
370
275
  * Adds a new beneficiary to the user account.
276
+ * For crypto wallet beneficiaries use `beneficiaryType: 3`, put the
277
+ * wallet address in `accountNumber` and set the `network`.
371
278
  * @param payload
372
279
  * @returns
373
280
  */
374
281
  async create(depositAccountObj) {
375
- if (!Tropipay.accessToken) {
376
- await this.tropipay.login();
377
- }
378
282
  try {
379
- const deposit = await this.tropipay.request.post("/api/v2/deposit_accounts", depositAccountObj, {
380
- headers: {
381
- "Content-Type": "application/json",
382
- Authorization: `Bearer ${Tropipay.accessToken}`,
383
- Accept: "application/json",
384
- },
385
- });
283
+ const deposit = await this.tropipay.request.post(`${API_BASE}/deposit_accounts`, depositAccountObj);
386
284
  return deposit.data;
387
285
  }
388
286
  catch (error) {
389
- return handleExceptions(error);
287
+ throw handleExceptions(error);
390
288
  }
391
289
  }
392
290
  /**
@@ -396,67 +294,192 @@ class DepositAccounts {
396
294
  * @returns
397
295
  */
398
296
  async get(id) {
399
- if (!Tropipay.accessToken) {
400
- await this.tropipay.login();
401
- }
402
297
  try {
403
- const deposit = await this.tropipay.request.get(`/api/v2/deposit_accounts/${id}`, {
404
- headers: {
405
- "Content-Type": "application/json",
406
- Authorization: `Bearer ${Tropipay.accessToken}`,
407
- Accept: "application/json",
408
- },
409
- });
298
+ const deposit = await this.tropipay.request.get(`${API_BASE}/deposit_accounts/${id}`);
410
299
  return deposit.data;
411
300
  }
412
301
  catch (error) {
413
- return handleExceptions(error);
302
+ throw handleExceptions(error);
414
303
  }
415
304
  }
416
305
  /**
417
306
  * Updates certain beneficiary data.
418
- * @param depositAccountObj
307
+ * @param depositAccountObj Object with the beneficiary id and the fields to update.
419
308
  * @returns
420
309
  */
421
310
  async update(depositAccountObj) {
422
- if (!Tropipay.accessToken) {
423
- await this.tropipay.login();
424
- }
425
311
  try {
426
- const deposit = await this.tropipay.request.put(`/api/v2/deposit_accounts/`, {
427
- headers: {
428
- "Content-Type": "application/json",
429
- Authorization: `Bearer ${Tropipay.accessToken}`,
430
- Accept: "application/json",
431
- },
432
- });
312
+ const deposit = await this.tropipay.request.put(`${API_BASE}/deposit_accounts`, depositAccountObj);
433
313
  return deposit.data;
434
314
  }
435
315
  catch (error) {
436
- return handleExceptions(error);
316
+ throw handleExceptions(error);
437
317
  }
438
318
  }
439
319
  /**
440
- * (UNTESTED) Deletes the beneficiary indicated by id
320
+ * Deletes the beneficiary indicated by id
441
321
  * @param id
442
322
  * @returns
443
323
  */
444
324
  async delete(id) {
445
- if (!Tropipay.accessToken) {
446
- await this.tropipay.login();
325
+ try {
326
+ const deposit = await this.tropipay.request.delete(`${API_BASE}/deposit_accounts/${id}`);
327
+ return deposit.data;
447
328
  }
329
+ catch (error) {
330
+ throw handleExceptions(error);
331
+ }
332
+ }
333
+ /**
334
+ * Validates a beneficiary account number (bank account, card or
335
+ * crypto wallet address) before creating it.
336
+ * @param payload Account number data to validate (e.g. { accountNumber, paymentType, network, currency })
337
+ * @returns
338
+ */
339
+ async validateAccountNumber(payload) {
448
340
  try {
449
- const deposit = await this.tropipay.request.delete(`/api/v2/deposit_accounts/${id}`, {
450
- headers: {
451
- "Content-Type": "application/json",
452
- Authorization: `Bearer ${Tropipay.accessToken}`,
453
- Accept: "application/json",
454
- },
341
+ const validation = await this.tropipay.request.post(`${API_BASE}/deposit_accounts/validate_account_number`, payload);
342
+ return validation.data;
343
+ }
344
+ catch (error) {
345
+ throw handleExceptions(error);
346
+ }
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Multi-account support. A Tropipay user can hold several accounts
352
+ * (one per currency). Use `list()` to discover the `accountId` values
353
+ * accepted by `paymentCards.create()` and `transfers.payout()`.
354
+ */
355
+ class Accounts {
356
+ tropipay;
357
+ constructor(tropipayInstance) {
358
+ this.tropipay = tropipayInstance;
359
+ }
360
+ /**
361
+ * List all the accounts of the current user with their id,
362
+ * accountNumber, currency, balance and enabled payment methods.
363
+ * @param type Optional comma-separated account types filter.
364
+ * @returns Array of Account objects.
365
+ */
366
+ async list(type) {
367
+ try {
368
+ const accounts = await this.tropipay.request.get(`${API_BASE}/accounts`, {
369
+ params: type ? { type } : undefined,
455
370
  });
456
- return deposit.data;
371
+ // accept both a plain array and a paginated { count, rows } body
372
+ const data = accounts.data;
373
+ return Array.isArray(data) ? data : data?.rows ?? [];
374
+ }
375
+ catch (error) {
376
+ throw handleExceptions(error);
377
+ }
378
+ }
379
+ /**
380
+ * Get the balance of every account of the user.
381
+ * @returns Balances for all accounts.
382
+ */
383
+ async allBalances() {
384
+ try {
385
+ const balances = await this.tropipay.request.get(`${API_BASE}/accounts/allBalance`);
386
+ return balances.data;
457
387
  }
458
388
  catch (error) {
459
- return handleExceptions(error);
389
+ throw handleExceptions(error);
390
+ }
391
+ }
392
+ /**
393
+ * Get the balance of one account by its account number
394
+ * (note: accountNumber, not account id — get it from `list()`).
395
+ * @param accountNumber The account number.
396
+ */
397
+ async balance(accountNumber) {
398
+ try {
399
+ const balance = await this.tropipay.request.get(`${API_BASE}/accounts/balance/${accountNumber}`);
400
+ return balance.data;
401
+ }
402
+ catch (error) {
403
+ throw handleExceptions(error);
404
+ }
405
+ }
406
+ /**
407
+ * List the movements of one account.
408
+ * @param accountId The account id (from `list()`).
409
+ * @param options Pagination: limit (max 50, default 20) and offset.
410
+ */
411
+ async movements(accountId, options = {}) {
412
+ try {
413
+ const movements = await this.tropipay.request.get(`${API_BASE}/accounts/${accountId}/movements`, {
414
+ params: { limit: options.limit ?? 20, offset: options.offset ?? 0 },
415
+ });
416
+ return movements.data;
417
+ }
418
+ catch (error) {
419
+ throw handleExceptions(error);
420
+ }
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Money transfers (payouts) to beneficiaries. Requires 2FA and the
426
+ * ALLOW_EXTERNAL_TRANSFER permission on the Tropipay account.
427
+ *
428
+ * Typical flow:
429
+ * 1. `simulate(payload)` to preview amounts and fees.
430
+ * 2. `requestSecurityCode()` to receive the 2FA code (SMS/email).
431
+ * 3. `payout({ ...payload, securityCode })` to execute the transfer.
432
+ */
433
+ class Transfers {
434
+ tropipay;
435
+ constructor(tropipayInstance) {
436
+ this.tropipay = tropipayInstance;
437
+ }
438
+ /**
439
+ * Simulate a payout without executing it: returns the resulting
440
+ * amounts, rates and fees for the given payload.
441
+ * Note the payload shape differs from `payout()`: it uses
442
+ * `currencyToPay`/`currencyToGet`, `amountToPay`/`amountToGet` and
443
+ * requires `accountId`.
444
+ * @param payload Simulation data (no securityCode needed).
445
+ */
446
+ async simulate(payload) {
447
+ try {
448
+ const simulation = await this.tropipay.request.post(`${API_BASE}/booking/payout/simulate`, payload);
449
+ return simulation.data;
450
+ }
451
+ catch (error) {
452
+ throw handleExceptions(error);
453
+ }
454
+ }
455
+ /**
456
+ * Execute a payout (external transfer) to a beneficiary.
457
+ * Requires the 2FA `securityCode` in the payload (use
458
+ * `requestSecurityCode()` first; in Development mode "123456" works).
459
+ * Supports multi-account via the optional `accountId` field.
460
+ * @param payload Payout data including securityCode.
461
+ */
462
+ async payout(payload) {
463
+ try {
464
+ const booking = await this.tropipay.request.post(`${API_BASE}/booking/payout`, payload);
465
+ return booking.data;
466
+ }
467
+ catch (error) {
468
+ throw handleExceptions(error);
469
+ }
470
+ }
471
+ /**
472
+ * Request the 2FA security code needed to confirm a payout.
473
+ * The code is delivered by SMS or email depending on the user's
474
+ * 2FA settings.
475
+ */
476
+ async requestSecurityCode() {
477
+ try {
478
+ const response = await this.tropipay.request.post(`${API_BASE}/booking/sendSecurityCode`, {});
479
+ return response.data;
480
+ }
481
+ catch (error) {
482
+ throw handleExceptions(error);
460
483
  }
461
484
  }
462
485
  }
@@ -467,19 +490,22 @@ class DepositAccounts {
467
490
  * @author Yosleivy Baez Acosta
468
491
  *
469
492
  */
493
+ const TOKEN_URL = `${API_BASE}/access/token`;
470
494
  class Tropipay {
471
495
  clientId;
472
496
  clientSecret;
473
497
  scopes;
474
498
  request;
475
- static accessToken;
476
- static refreshToken;
477
- static expiresIn;
499
+ // Per instance, so several credentials (or environments) never share a token
500
+ accessToken = null;
501
+ refreshToken = null;
502
+ expiresIn = null;
478
503
  serverMode;
479
504
  hooks;
480
505
  paymentCards;
481
506
  depositAccounts;
482
- mediationPaymentCard;
507
+ accounts;
508
+ transfers;
483
509
  /**
484
510
  * Initializes a new instance of the Tropipay class.
485
511
  *
@@ -512,87 +538,77 @@ class Tropipay {
512
538
  this.serverMode = config.serverMode || "Development";
513
539
  const tpp_env = this.serverMode === "Production"
514
540
  ? "https://www.tropipay.com"
515
- : "https://tropipay-dev.herokuapp.com";
541
+ : "https://sandbox.tropipay.me";
516
542
  this.request = axios.create({
517
543
  baseURL: config.customTropipayUrl || tpp_env,
518
544
  headers: {
519
545
  "Content-Type": "application/json",
520
546
  Accept: "application/json",
521
- Authorization: `Bearer ${Tropipay.accessToken}`,
522
547
  },
523
548
  });
524
- // Add request interceptor for Token expired
549
+ // Log in (or refresh an expired token) and attach the current token to
550
+ // every request. The token endpoint itself is skipped, otherwise login()
551
+ // would re-enter this interceptor forever.
525
552
  this.request.interceptors.request.use(async (config) => {
553
+ if (config.url === TOKEN_URL)
554
+ return config;
526
555
  const currentTimestamp = Math.floor(Date.now() / 1000); // Current time in seconds
527
- if (Tropipay.expiresIn && Tropipay.expiresIn < currentTimestamp) {
528
- // Token has expired, attempt to refresh it
529
- try {
530
- await this.login();
531
- }
532
- catch (error) {
533
- // Handle token refresh error
534
- Tropipay.accessToken = null;
535
- Tropipay.refreshToken = null;
536
- throw handleExceptions(error);
537
- }
556
+ const expired = this.expiresIn !== null && this.expiresIn < currentTimestamp;
557
+ if (!this.accessToken || expired) {
558
+ await this.login();
538
559
  }
560
+ config.headers.Authorization = `Bearer ${this.accessToken}`;
539
561
  return config;
540
562
  }, (error) => {
541
563
  return Promise.reject(error);
542
564
  });
543
565
  this.hooks = new TropipayHooks(this);
544
566
  this.paymentCards = new PaymentCard(this);
545
- this.mediationPaymentCard = new MediationPaymentCard(this);
546
567
  this.depositAccounts = new DepositAccounts(this);
568
+ this.accounts = new Accounts(this);
569
+ this.transfers = new Transfers(this);
547
570
  }
548
571
  async login() {
549
572
  try {
550
- if (Tropipay.refreshToken) {
551
- const { data } = await this.request.post("/api/v2/access/token", {
573
+ if (this.refreshToken) {
574
+ const { data } = await this.request.post(TOKEN_URL, {
552
575
  client_id: this.clientId,
553
576
  client_secret: this.clientSecret,
554
577
  grant_type: "refresh_token",
555
- refresh_token: Tropipay.refreshToken,
556
- }, {
557
- headers: {
558
- "Content-Type": "application/json",
559
- Accept: "application/json",
560
- },
578
+ refresh_token: this.refreshToken,
561
579
  });
580
+ this.accessToken = data.access_token;
581
+ this.refreshToken = data.refresh_token;
582
+ this.expiresIn = data.expires_in;
562
583
  return data;
563
584
  }
564
585
  // normal credetials login
565
- const { data } = await this.request.post("/api/v2/access/token", {
586
+ const { data } = await this.request.post(TOKEN_URL, {
566
587
  client_id: this.clientId,
567
588
  client_secret: this.clientSecret,
568
589
  grant_type: "client_credentials",
569
590
  scope: this.scopes.join(" "), // "ALLOW_GET_PROFILE_DATA ALLOW_PAYMENT_IN ALLOW_EXTERNAL_CHARGE KYC3_FULL_ALLOW ALLOW_PAYMENT_OUT ALLOW_MARKET_PURCHASES ALLOW_GET_BALANCE ALLOW_GET_MOVEMENT_LIST ALLOW_GET_CREDENTIAL",
570
- }, {
571
- headers: {
572
- "Content-Type": "application/json",
573
- Accept: "application/json",
574
- },
575
591
  });
576
- Tropipay.accessToken = data.access_token;
577
- Tropipay.refreshToken = data.refresh_token;
578
- Tropipay.expiresIn = data.expires_in;
592
+ this.accessToken = data.access_token;
593
+ this.refreshToken = data.refresh_token;
594
+ this.expiresIn = data.expires_in;
579
595
  return data;
580
596
  }
581
597
  catch (error) {
582
- Tropipay.accessToken = null;
583
- Tropipay.refreshToken = null;
584
- Tropipay.expiresIn = null;
598
+ this.accessToken = null;
599
+ this.refreshToken = null;
600
+ this.expiresIn = null;
585
601
  throw handleExceptions(error);
586
602
  }
587
603
  }
588
604
  /**
589
605
  * Get the list of all supported countries by Tropipay.
590
606
  * @returns Array of Countries Data
591
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/bfac21259e2ff-getting-users-countries-list
607
+ * @see https://doc.tropipay.com/docs/api-reference/countries
592
608
  */
593
609
  async countries() {
594
610
  try {
595
- const countries = await this.request.get("/api/v2/countries");
611
+ const countries = await this.request.get(`${API_BASE}/countries`);
596
612
  return countries.data;
597
613
  }
598
614
  catch (error) {
@@ -600,21 +616,14 @@ class Tropipay {
600
616
  }
601
617
  }
602
618
  /**
603
- * Get user balance
619
+ * Get balance of the user's default account.
620
+ * For per-account balances use `accounts.balance()` or
621
+ * `accounts.allBalances()`.
604
622
  * @returns balance Object { balance: number, pendingIn: number, pendingOut: number }
605
623
  */
606
624
  async getBalance() {
607
- if (!Tropipay.accessToken) {
608
- await this.login();
609
- }
610
625
  try {
611
- const balance = await this.request.get("/api/v2/users/balance", {
612
- headers: {
613
- "Content-Type": "application/json",
614
- Authorization: `Bearer ${Tropipay.accessToken}`,
615
- Accept: "application/json",
616
- },
617
- });
626
+ const balance = await this.request.get(`${API_BASE}/users/balance`);
618
627
  return balance.data;
619
628
  }
620
629
  catch (error) {
@@ -627,15 +636,15 @@ class Tropipay {
627
636
  * when adding new beneficiaries to some user.
628
637
  *
629
638
  * @returns Array of Country Objects
630
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/3cfe5504f0524-getting-list-of-beneficiary-countries
639
+ * @see https://doc.tropipay.com/docs/api-reference/countries
631
640
  */
632
641
  async destinations() {
633
642
  try {
634
- const countries = await this.request.get("/api/v2/countries/destinations");
643
+ const countries = await this.request.get(`${API_BASE}/countries/destinations`);
635
644
  return countries.data;
636
645
  }
637
646
  catch (error) {
638
- throw new Error(`Could not retrieve the destination countries list`);
647
+ throw handleExceptions(error);
639
648
  }
640
649
  }
641
650
  /**
@@ -643,16 +652,9 @@ class Tropipay {
643
652
  * @returns Array of account Object or throws an error
644
653
  */
645
654
  async favorites() {
646
- if (!Tropipay.accessToken) {
647
- await this.login();
648
- }
649
655
  try {
650
- const favoritesList = await this.request.get("/api/v2/paymentcards/favorites", {
651
- headers: {
652
- "Content-Type": "application/json",
653
- Authorization: `Bearer ${Tropipay.accessToken}`,
654
- Accept: "application/json",
655
- },
656
+ const favoritesList = await this.request.get(`${API_BASE}/paymentcards/filters`, {
657
+ params: { favorite: true },
656
658
  });
657
659
  return favoritesList?.data?.rows;
658
660
  }
@@ -662,20 +664,16 @@ class Tropipay {
662
664
  }
663
665
  /**
664
666
  * List all account movements. You can optionaly specify
665
- * offset and limit params for pagination.
667
+ * offset and limit params for pagination (limit is capped
668
+ * to 50 by the API).
669
+ * For the movements of one specific account use
670
+ * `accounts.movements(accountId)`.
666
671
  * @returns
667
672
  */
668
673
  async movements(offset = 0, limit = 10) {
669
- if (!Tropipay.accessToken)
670
- await this.login();
671
674
  try {
672
- const movements = await this.request.get("/api/v2/movements", {
675
+ const movements = await this.request.get(`${API_BASE}/movements`, {
673
676
  params: { limit: limit, offset: offset },
674
- headers: {
675
- "Content-Type": "application/json",
676
- Accept: "application/json",
677
- Authorization: `Bearer ${Tropipay.accessToken}`,
678
- },
679
677
  });
680
678
  return movements.data;
681
679
  }
@@ -688,10 +686,8 @@ class Tropipay {
688
686
  * @returns account object
689
687
  */
690
688
  async profile() {
691
- if (!Tropipay.accessToken)
692
- await this.login();
693
689
  try {
694
- const profile = await this.request.get("/api/users/profile");
690
+ const profile = await this.request.get(`${API_BASE}/users/profile`);
695
691
  return profile.data;
696
692
  }
697
693
  catch (error) {
@@ -704,51 +700,16 @@ class Tropipay {
704
700
  * @param originCurrency Target currency code supported by Tropipay.
705
701
  * @param targetCurrency Must be 'EUR'? (not documented by Tropipay)
706
702
  * @returns Conversion rate (number)
707
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/85163f6f28b23-get-rate
703
+ * @see https://doc.tropipay.com/docs/api-reference/movements
708
704
  */
709
705
  async rates(originCurrency, targetCurrency = "EUR") {
710
- if (!Tropipay.accessToken) {
711
- await this.login();
712
- }
713
706
  try {
714
- const rates = await this.request.post("/api/v2/movements/get_rate", {
707
+ const rates = await this.request.post(`${API_BASE}/movements/get_rate`, {
715
708
  currencyFrom: originCurrency,
716
709
  currencyTo: targetCurrency,
717
- }, {
718
- headers: {
719
- "Content-Type": "application/json",
720
- Accept: "application/json",
721
- Authorization: `Bearer ${Tropipay.accessToken}`,
722
- },
723
710
  });
724
- return rates.data.rate;
725
- }
726
- catch (error) {
727
- throw handleExceptions(error);
728
- }
729
- }
730
- /**
731
- * (ONLY in Bussiness Accounts)
732
- * An escrow payment link. This allows a payment to be made to persons
733
- * belonging or not to the TropiPay platform with the particularity
734
- * that the payment will be held in custody or retained until it is
735
- * released with the approval of the payer.
736
- * @deprecated This method is no longer supported and may be removed in a future release.
737
- * @see https://tpp.stoplight.io/docs/tropipay-api-doc/12a128ff971e4-creating-a-mediation-payment-card
738
- * @param config Payload with the payment details
739
- */
740
- async createMediationPaymentCard(config) {
741
- if (!Tropipay.accessToken)
742
- await this.login();
743
- try {
744
- const mediation = await this.request.post("/api/v2/paymentcards/mediation", config, {
745
- headers: {
746
- "Content-Type": "application/json",
747
- Authorization: `Bearer ${Tropipay.accessToken}`,
748
- Accept: "application/json",
749
- },
750
- });
751
- return mediation.data;
711
+ // the v3 API returns the rate as a numeric string
712
+ return Number(rates.data.rate);
752
713
  }
753
714
  catch (error) {
754
715
  throw handleExceptions(error);
@@ -769,20 +730,11 @@ class Tropipay {
769
730
  * the code received via SMS in Production (obtained via requestSecurityCode()).
770
731
  */
771
732
  async refundMovement(orderCode, amount, securityCode) {
772
- if (!Tropipay.accessToken) {
773
- await this.login();
774
- }
775
733
  if (!this.scopes.includes("ALLOW_REFUND")) {
776
734
  throw new TropipayJSException("The credential does not have the ALLOW_REFUND scope required to perform refunds. If you believe your account should have this permission, please contact Tropipay support.", 403, null);
777
735
  }
778
736
  try {
779
- const response = await this.request.post("/api/v3/movements/in/refund", { orderCode, amount, securityCode }, {
780
- headers: {
781
- "Content-Type": "application/json",
782
- Accept: "application/json",
783
- Authorization: `Bearer ${Tropipay.accessToken}`,
784
- },
785
- });
737
+ const response = await this.request.post(`${API_BASE}/movements/in/refund`, { orderCode, amount, securityCode });
786
738
  return response.data;
787
739
  }
788
740
  catch (error) {
@@ -802,17 +754,8 @@ class Tropipay {
802
754
  * @returns The API response confirming the code was sent
803
755
  */
804
756
  async requestSecurityCode(type = "sms") {
805
- if (!Tropipay.accessToken) {
806
- await this.login();
807
- }
808
757
  try {
809
- const response = await this.request.post("/api/v3/users/sendSecurityCode", { type }, {
810
- headers: {
811
- "Content-Type": "application/json",
812
- Accept: "application/json",
813
- Authorization: `Bearer ${Tropipay.accessToken}`,
814
- },
815
- });
758
+ const response = await this.request.post(`${API_BASE}/users/sendSecurityCode`, { type });
816
759
  return response.data;
817
760
  }
818
761
  catch (error) {
@@ -820,13 +763,6 @@ class Tropipay {
820
763
  }
821
764
  }
822
765
  }
823
- class ClientSideUtils {
824
- constructor(tropipayInstance) {
825
- throw Error(`Not implemented yet`);
826
- }
827
- }
828
-
829
- const MAX_IMAGE_SIZE_MB = 1;
830
766
 
831
767
  class ServerSideUtils {
832
768
  tropipay;
@@ -853,23 +789,71 @@ class ServerSideUtils {
853
789
  }
854
790
  /**
855
791
  * Checks if the provided base64 string represents a square image.
792
+ * Supports PNG and JPEG images (dimensions are read directly from
793
+ * the binary header, no DOM required).
856
794
  *
857
795
  * @param {string} base64String - The base64 string of the image
858
796
  * @return {Promise<boolean>} A Promise that resolves to a boolean indicating whether the image is square
859
797
  */
860
798
  static async isBase64ImageSquare(base64String) {
861
- return new Promise((resolve, reject) => {
862
- const img = new Image();
863
- img.onload = () => {
864
- // Check if the image has a 1:1 aspect ratio
865
- const isSquare = img.width === img.height;
866
- resolve(isSquare);
867
- };
868
- img.onerror = (error) => {
869
- reject(error);
799
+ const dimensions = ServerSideUtils.getImageDimensions(base64String);
800
+ return dimensions.width === dimensions.height;
801
+ }
802
+ /**
803
+ * Reads the width/height of a base64 encoded PNG or JPEG image
804
+ * from its binary header.
805
+ *
806
+ * @param {string} base64String - base64 image, with or without the data: prefix
807
+ * @return {{width: number, height: number}} the image dimensions
808
+ */
809
+ static getImageDimensions(base64String) {
810
+ const base64Data = base64String.replace(/^data:image\/\w+;base64,/, "");
811
+ const buffer = Buffer.from(base64Data, "base64");
812
+ // PNG signature: 89 50 4E 47, IHDR width/height at offsets 16/20
813
+ if (buffer.length > 24 &&
814
+ buffer[0] === 0x89 &&
815
+ buffer[1] === 0x50 &&
816
+ buffer[2] === 0x4e &&
817
+ buffer[3] === 0x47) {
818
+ return {
819
+ width: buffer.readUInt32BE(16),
820
+ height: buffer.readUInt32BE(20),
870
821
  };
871
- img.src = base64String;
872
- });
822
+ }
823
+ // JPEG signature: FF D8. Scan segments for a SOFn marker with the frame size.
824
+ if (buffer.length > 4 && buffer[0] === 0xff && buffer[1] === 0xd8) {
825
+ let offset = 2;
826
+ while (offset + 9 < buffer.length) {
827
+ if (buffer[offset] !== 0xff) {
828
+ offset++;
829
+ continue;
830
+ }
831
+ const marker = buffer[offset + 1];
832
+ // 0xFF fill bytes may pad the stream before a marker
833
+ if (marker === 0xff) {
834
+ offset++;
835
+ continue;
836
+ }
837
+ // standalone markers (TEM, RST0-RST7) carry no length field
838
+ if (marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {
839
+ offset += 2;
840
+ continue;
841
+ }
842
+ // SOF0-SOF15 markers except DHT (C4), JPG (C8) and DAC (CC)
843
+ if (marker >= 0xc0 &&
844
+ marker <= 0xcf &&
845
+ marker !== 0xc4 &&
846
+ marker !== 0xc8 &&
847
+ marker !== 0xcc) {
848
+ return {
849
+ height: buffer.readUInt16BE(offset + 5),
850
+ width: buffer.readUInt16BE(offset + 7),
851
+ };
852
+ }
853
+ offset += 2 + buffer.readUInt16BE(offset + 2);
854
+ }
855
+ }
856
+ throw new Error("Unsupported image format: only PNG and JPEG are allowed");
873
857
  }
874
858
  /**
875
859
  * Takes a local file path and returns a base64 representation of the file content.
@@ -910,11 +894,10 @@ class ServerSideUtils {
910
894
  console.error("Not a valid base64 image");
911
895
  throw new Error("Not a valid base64 image");
912
896
  }
913
- // TODO: use constants intead of magic numbers here
914
- const isSizeLessThan2MB = base64Image.length * 0.75 <= MAX_IMAGE_SIZE_MB * 1024 * 1024;
915
- if (!isSizeLessThan2MB) {
916
- console.error(`The image should be less than 2mb`);
917
- throw new Error(`The image should be less than 2mb`);
897
+ const isSizeValid = base64Image.length * 0.75 <= MAX_IMAGE_SIZE_MB * 1024 * 1024;
898
+ if (!isSizeValid) {
899
+ console.error(`The image should be less than ${MAX_IMAGE_SIZE_MB}mb`);
900
+ throw new Error(`The image should be less than ${MAX_IMAGE_SIZE_MB}mb`);
918
901
  }
919
902
  // all is fine
920
903
  return true;
@@ -926,6 +909,97 @@ class ServerSideUtils {
926
909
  }
927
910
  }
928
911
 
912
+ /**
913
+ * Payment reasons accepted in the `reasonId` field.
914
+ */
915
+ exports.Reasons = void 0;
916
+ (function (Reasons) {
917
+ Reasons[Reasons["HOUSING_ARRANGEMENT"] = 1] = "HOUSING_ARRANGEMENT";
918
+ Reasons[Reasons["FINANCIAL_AID"] = 2] = "FINANCIAL_AID";
919
+ Reasons[Reasons["FAMILY_SUPPORT"] = 3] = "FAMILY_SUPPORT";
920
+ Reasons[Reasons["TRAVEL_FUND"] = 4] = "TRAVEL_FUND";
921
+ Reasons[Reasons["REAL_ESTATE_PURCHASE"] = 5] = "REAL_ESTATE_PURCHASE";
922
+ Reasons[Reasons["FURNITURE_PURCHASE"] = 6] = "FURNITURE_PURCHASE";
923
+ Reasons[Reasons["EDUCATION"] = 7] = "EDUCATION";
924
+ Reasons[Reasons["MEDICAL_EXPENSES"] = 8] = "MEDICAL_EXPENSES";
925
+ Reasons[Reasons["OTHER"] = 9] = "OTHER";
926
+ Reasons[Reasons["DEBT_PAYMENT"] = 10] = "DEBT_PAYMENT";
927
+ Reasons[Reasons["TOURISM"] = 11] = "TOURISM";
928
+ Reasons[Reasons["SELF_SHIPPING"] = 12] = "SELF_SHIPPING";
929
+ Reasons[Reasons["ACCOUNT_ACTIVATION"] = 13] = "ACCOUNT_ACTIVATION";
930
+ Reasons[Reasons["SPORTS_ACTIVITIES"] = 14] = "SPORTS_ACTIVITIES";
931
+ Reasons[Reasons["DONATION"] = 15] = "DONATION";
932
+ Reasons[Reasons["AFFILIATE_COMMISSION"] = 16] = "AFFILIATE_COMMISSION";
933
+ Reasons[Reasons["SALARY"] = 17] = "SALARY";
934
+ Reasons[Reasons["SAVINGS"] = 18] = "SAVINGS";
935
+ Reasons[Reasons["RENT_AND_LEASING"] = 19] = "RENT_AND_LEASING";
936
+ Reasons[Reasons["SHARED_EXPENSES"] = 20] = "SHARED_EXPENSES";
937
+ Reasons[Reasons["SERVICE_PAYMENT"] = 21] = "SERVICE_PAYMENT";
938
+ Reasons[Reasons["GIFT"] = 22] = "GIFT";
939
+ Reasons[Reasons["CRYPTOCURRENCY_PURCHASE"] = 23] = "CRYPTOCURRENCY_PURCHASE";
940
+ Reasons[Reasons["OPERATING_EXPENSES"] = 24] = "OPERATING_EXPENSES";
941
+ Reasons[Reasons["CURRENCY_EXCHANGE"] = 25] = "CURRENCY_EXCHANGE";
942
+ Reasons[Reasons["ACCOMMODATION"] = 26] = "ACCOMMODATION";
943
+ Reasons[Reasons["EQUIPMENT_PURCHASE"] = 27] = "EQUIPMENT_PURCHASE";
944
+ Reasons[Reasons["CONSULTING"] = 28] = "CONSULTING";
945
+ Reasons[Reasons["SOFTWARE_DEVELOPMENT"] = 29] = "SOFTWARE_DEVELOPMENT";
946
+ Reasons[Reasons["REFUND"] = 30] = "REFUND";
947
+ Reasons[Reasons["PACKAGE_DELIVERY"] = 31] = "PACKAGE_DELIVERY";
948
+ Reasons[Reasons["PERSONAL_EXPENSES"] = 32] = "PERSONAL_EXPENSES";
949
+ Reasons[Reasons["INVESTMENT"] = 33] = "INVESTMENT";
950
+ Reasons[Reasons["BILL_PAYMENT"] = 34] = "BILL_PAYMENT";
951
+ Reasons[Reasons["HOST_PAYMENT"] = 35] = "HOST_PAYMENT";
952
+ Reasons[Reasons["TRANSPORTATION"] = 36] = "TRANSPORTATION";
953
+ Reasons[Reasons["LOAN"] = 37] = "LOAN";
954
+ Reasons[Reasons["BONUS"] = 38] = "BONUS";
955
+ Reasons[Reasons["HALLOWEEN_REMITTANCE"] = 39] = "HALLOWEEN_REMITTANCE";
956
+ Reasons[Reasons["PLINK_REMITTANCE"] = 41] = "PLINK_REMITTANCE";
957
+ Reasons[Reasons["R1_2023"] = 78] = "R1_2023";
958
+ Reasons[Reasons["HAPPYWEEK"] = 79] = "HAPPYWEEK";
959
+ Reasons[Reasons["SENDING_YOU_A_KISS"] = 80] = "SENDING_YOU_A_KISS";
960
+ })(exports.Reasons || (exports.Reasons = {}));
961
+
962
+ const DepositAccountTypesList = {
963
+ /**
964
+ * Banco Metropolitano (Cuba) Bank Account
965
+ */
966
+ BANMET_BANK_ACCOUNT: 0,
967
+ /**
968
+ * Banco Popular de Ahorro
969
+ */
970
+ BPA_BANK_ACCOUNT: 1,
971
+ /**
972
+ * Banco de Credito y Comercio (Cuba) Bank Account
973
+ */
974
+ BANDEC_BANK_ACCOUNT: 2,
975
+ /**
976
+ * Banco Metropilitano (Cuba) card
977
+ */
978
+ BANMET_CARD: 3,
979
+ /**
980
+ * Banco Popular de Ahorro (Cuba) card
981
+ */
982
+ BPA_CARD: 4,
983
+ /**
984
+ * Not available anymore
985
+ * @deprecated
986
+ */
987
+ AIS_CUC_CARD: 5,
988
+ /**
989
+ * Not available
990
+ * @deprecated
991
+ */
992
+ AIS_USD_CARD: 6,
993
+ /**
994
+ * For international bank accounts
995
+ */
996
+ OTHER: 7,
997
+ /**
998
+ * Banco de Credito y comercio card
999
+ */
1000
+ BANDEC_CARD: 8,
1001
+ };
1002
+
929
1003
  const SERVER_MODE = "Development"; // Move the constant here
930
1004
 
931
1005
  /**
@@ -936,7 +1010,6 @@ const SERVER_MODE = "Development"; // Move the constant here
936
1010
  * Developed by Yosleivy Baez Acosta
937
1011
  * GitHub: https://github.com/yosle/tropipayjs
938
1012
  *
939
- * @version 0.1.11
940
1013
  * @license MIT
941
1014
  */
942
1015
  if (typeof window !== "undefined") {
@@ -945,9 +1018,15 @@ if (typeof window !== "undefined") {
945
1018
  throw new Error(err_msg);
946
1019
  }
947
1020
 
948
- exports.ClientSideUtils = ClientSideUtils;
1021
+ exports.API_BASE = API_BASE;
1022
+ exports.Accounts = Accounts;
1023
+ exports.DepositAccountTypesList = DepositAccountTypesList;
1024
+ exports.DepositAccounts = DepositAccounts;
949
1025
  exports.MAX_IMAGE_SIZE_MB = MAX_IMAGE_SIZE_MB;
1026
+ exports.PaymentCard = PaymentCard;
950
1027
  exports.SERVER_MODE = SERVER_MODE;
951
1028
  exports.ServerSideUtils = ServerSideUtils;
1029
+ exports.Transfers = Transfers;
952
1030
  exports.Tropipay = Tropipay;
1031
+ exports.TropipayHooks = TropipayHooks;
953
1032
  //# sourceMappingURL=index.js.map