tonder-web-sdk 1.11.12 → 1.12.0-beta.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.
- package/.idea/prettier.xml +6 -0
- package/.idea/workspace.xml +96 -11
- package/README.md +0 -3
- package/package.json +3 -1
- package/src/classes/3dsHandler.js +1 -4
- package/src/classes/BaseInlineCheckout.js +298 -0
- package/src/classes/LiteInlineCheckout.js +101 -0
- package/src/classes/inlineCheckout.js +63 -286
- package/src/data/apmApi.js +44 -0
- package/src/data/businessApi.js +19 -0
- package/src/data/cardApi.js +116 -0
- package/src/data/checkoutApi.js +81 -0
- package/src/data/customerApi.js +37 -0
- package/src/data/index.js +17 -0
- package/src/data/openPayApi.js +16 -0
- package/src/data/skyflowApi.js +18 -0
- package/src/helpers/skyflow.js +76 -15
- package/src/helpers/template.js +7 -1
- package/src/helpers/utils.js +64 -79
- package/src/index-dev.js +96 -14
- package/src/index.html +119 -8
- package/src/shared/constants/paymentMethodAPM.js +63 -0
- package/src/shared/constants/tonderUrl.js +8 -0
- package/types/index.d.ts +14 -0
- package/v1/bundle.min.js +3 -3
- package/src/data/api.js +0 -193
- package/src/helpers/constants.js +0 -64
|
@@ -1,31 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { cardTemplateSkeleton } from '../helpers/template-skeleton.js'
|
|
1
|
+
import {apmItemsTemplate, cardItemsTemplate, cardTemplate} from '../helpers/template.js'
|
|
3
2
|
import {
|
|
4
|
-
getBusiness,
|
|
5
|
-
customerRegister,
|
|
6
|
-
createOrder,
|
|
7
|
-
createPayment,
|
|
8
|
-
startCheckoutRouter,
|
|
9
|
-
getOpenpayDeviceSessionID,
|
|
10
|
-
getCustomerCards,
|
|
11
|
-
registerCard,
|
|
12
|
-
deleteCustomerCard,
|
|
13
|
-
getCustomerAPMs
|
|
14
|
-
} from '../data/api';
|
|
15
|
-
import {
|
|
16
|
-
showError,
|
|
17
|
-
getBrowserInfo,
|
|
18
|
-
mapCards,
|
|
19
|
-
showMessage,
|
|
20
3
|
clearSpace,
|
|
21
|
-
injectMercadoPagoSecurity
|
|
4
|
+
injectMercadoPagoSecurity,
|
|
5
|
+
mapCards,
|
|
6
|
+
showError,
|
|
7
|
+
showMessage
|
|
22
8
|
} from '../helpers/utils';
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
|
|
9
|
+
import {initSkyflow} from '../helpers/skyflow'
|
|
10
|
+
import {globalLoader} from './globalLoader.js';
|
|
11
|
+
import {BaseInlineCheckout} from "./BaseInlineCheckout";
|
|
12
|
+
import {
|
|
13
|
+
fetchCustomerCards,
|
|
14
|
+
removeCustomerCard,
|
|
15
|
+
saveCustomerCard,
|
|
16
|
+
fetchCustomerAPMs
|
|
17
|
+
} from "../data";
|
|
27
18
|
|
|
28
|
-
export class InlineCheckout {
|
|
19
|
+
export class InlineCheckout extends BaseInlineCheckout{
|
|
29
20
|
static injected = false;
|
|
30
21
|
static cardsInjected = false
|
|
31
22
|
static apmsInjected = false
|
|
@@ -33,7 +24,6 @@ export class InlineCheckout {
|
|
|
33
24
|
deletingCards = [];
|
|
34
25
|
customer = {}
|
|
35
26
|
items = []
|
|
36
|
-
baseUrl = null
|
|
37
27
|
collectContainer = null
|
|
38
28
|
merchantData = {}
|
|
39
29
|
cartTotal = null
|
|
@@ -56,36 +46,14 @@ export class InlineCheckout {
|
|
|
56
46
|
mode = "stage",
|
|
57
47
|
apiKey,
|
|
58
48
|
returnUrl,
|
|
59
|
-
successUrl,
|
|
60
49
|
renderPaymentButton = false,
|
|
61
50
|
callBack = () => { },
|
|
62
51
|
styles
|
|
63
52
|
}) {
|
|
64
|
-
|
|
65
|
-
this.returnUrl = returnUrl;
|
|
66
|
-
this.successUrl = successUrl;
|
|
53
|
+
super({ mode, apiKey, returnUrl, callBack });
|
|
67
54
|
this.renderPaymentButton = renderPaymentButton;
|
|
68
|
-
this.callBack = callBack;
|
|
69
55
|
this.customStyles = styles
|
|
70
|
-
this.mode = mode
|
|
71
|
-
this.baseUrl = this.#getBaseUrl()
|
|
72
|
-
|
|
73
|
-
this.abortController = new AbortController()
|
|
74
56
|
this.abortRefreshCardsController = new AbortController()
|
|
75
|
-
this.process3ds = new ThreeDSHandler(
|
|
76
|
-
{ apiKey: apiKey, baseUrl: this.baseUrl, successUrl: successUrl }
|
|
77
|
-
)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
#getBaseUrl() {
|
|
81
|
-
const modeUrls = {
|
|
82
|
-
'production': 'https://app.tonder.io',
|
|
83
|
-
'sandbox': 'https://sandbox.tonder.io',
|
|
84
|
-
'stage': 'https://stage.tonder.io',
|
|
85
|
-
'development': 'http://localhost:8000',
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
return modeUrls[this.mode] || modeUrls['stage']
|
|
89
57
|
}
|
|
90
58
|
|
|
91
59
|
#mountPayButton() {
|
|
@@ -118,90 +86,7 @@ export class InlineCheckout {
|
|
|
118
86
|
}
|
|
119
87
|
}
|
|
120
88
|
|
|
121
|
-
|
|
122
|
-
const iframe = response?.next_action?.iframe_resources?.iframe
|
|
123
|
-
|
|
124
|
-
if (iframe) {
|
|
125
|
-
this.process3ds.loadIframe().then(() => {
|
|
126
|
-
//TODO: Check if this will be necessary on the frontend side
|
|
127
|
-
// after some the tests in production, since the 3DS process
|
|
128
|
-
// doesn't works properly on the sandbox environment
|
|
129
|
-
// setTimeout(() => {
|
|
130
|
-
// process3ds.verifyTransactionStatus();
|
|
131
|
-
// }, 10000);
|
|
132
|
-
this.process3ds.verifyTransactionStatus();
|
|
133
|
-
}).catch((error) => {
|
|
134
|
-
console.log('Error loading iframe:', error)
|
|
135
|
-
})
|
|
136
|
-
} else {
|
|
137
|
-
const redirectUrl = this.process3ds.getRedirectUrl()
|
|
138
|
-
if (redirectUrl) {
|
|
139
|
-
this.process3ds.redirectToChallenge()
|
|
140
|
-
} else {
|
|
141
|
-
return response;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
payment(data) {
|
|
147
|
-
return new Promise(async (resolve, reject) => {
|
|
148
|
-
try {
|
|
149
|
-
this.#handleCustomer(data.customer)
|
|
150
|
-
this.setCartTotal(data.cart?.total)
|
|
151
|
-
this.setCartItems(data.cart?.items)
|
|
152
|
-
this.#handleMetadata(data)
|
|
153
|
-
this.#handleCurrency(data)
|
|
154
|
-
this.#handleCard(data)
|
|
155
|
-
const response = await this.#checkout()
|
|
156
|
-
this.process3ds.setPayload(response)
|
|
157
|
-
this.callBack(response);
|
|
158
|
-
const payload = await this.handle3dsRedirect(response)
|
|
159
|
-
if (payload) {
|
|
160
|
-
resolve(response);
|
|
161
|
-
}
|
|
162
|
-
} catch (error) {
|
|
163
|
-
reject(error);
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
#handleCustomer(customer) {
|
|
169
|
-
if (!customer) return
|
|
170
|
-
|
|
171
|
-
this.firstName = customer?.firstName
|
|
172
|
-
this.lastName = customer?.lastName
|
|
173
|
-
this.country = customer?.country
|
|
174
|
-
this.address = customer?.street
|
|
175
|
-
this.city = customer?.city
|
|
176
|
-
this.state = customer?.state
|
|
177
|
-
this.postCode = customer?.postCode
|
|
178
|
-
this.email = customer?.email
|
|
179
|
-
this.phone = customer?.phone
|
|
180
|
-
this.customer = customer
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
#handleMetadata(data) {
|
|
184
|
-
this.metadata = data?.metadata
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
#handleCurrency(data) {
|
|
188
|
-
this.currency = data?.currency
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
#handleCard(data) {
|
|
192
|
-
this.card = data?.card
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
setCartItems(items) {
|
|
196
|
-
this.cartItems = items
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
configureCheckout(data) {
|
|
200
|
-
if ('customer' in data)
|
|
201
|
-
this.#handleCustomer(data['customer'])
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
setCartTotal(total) {
|
|
89
|
+
_setCartTotal(total) {
|
|
205
90
|
this.cartTotal = total
|
|
206
91
|
this.#updatePayButton()
|
|
207
92
|
}
|
|
@@ -237,47 +122,6 @@ export class InlineCheckout {
|
|
|
237
122
|
});
|
|
238
123
|
}
|
|
239
124
|
|
|
240
|
-
async verify3dsTransaction () {
|
|
241
|
-
globalLoader.show()
|
|
242
|
-
const result3ds = await this.process3ds.verifyTransactionStatus()
|
|
243
|
-
const resultCheckout = await this.resumeCheckout(result3ds)
|
|
244
|
-
this.process3ds.setPayload(resultCheckout)
|
|
245
|
-
globalLoader.remove()
|
|
246
|
-
return this.handle3dsRedirect(resultCheckout)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
async resumeCheckout(response) {
|
|
251
|
-
// Stop the routing process if the transaction is either hard declined or successful
|
|
252
|
-
if (response?.decline?.error_type === "Hard") {
|
|
253
|
-
return response
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (["Success", "Authorized"].includes(response?.transaction_status)) {
|
|
257
|
-
return response;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (response) {
|
|
261
|
-
globalLoader.show()
|
|
262
|
-
const routerItems = {
|
|
263
|
-
checkout_id: response?.checkout?.id,
|
|
264
|
-
};
|
|
265
|
-
try {
|
|
266
|
-
const routerResponse = await startCheckoutRouter(
|
|
267
|
-
this.baseUrl,
|
|
268
|
-
this.apiKeyTonder,
|
|
269
|
-
routerItems
|
|
270
|
-
);
|
|
271
|
-
return routerResponse
|
|
272
|
-
} catch (error) {
|
|
273
|
-
// throw error
|
|
274
|
-
} finally {
|
|
275
|
-
globalLoader.remove()
|
|
276
|
-
}
|
|
277
|
-
return response
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
125
|
#mount(containerTonderCheckout) {
|
|
282
126
|
containerTonderCheckout.innerHTML = cardTemplate({renderPaymentButton: this.renderPaymentButton, customStyles: this.customStyles});
|
|
283
127
|
globalLoader.show()
|
|
@@ -285,22 +129,9 @@ export class InlineCheckout {
|
|
|
285
129
|
InlineCheckout.injected = true;
|
|
286
130
|
}
|
|
287
131
|
|
|
288
|
-
async #fetchMerchantData() {
|
|
289
|
-
this.merchantData = await getBusiness(
|
|
290
|
-
this.baseUrl,
|
|
291
|
-
this.apiKeyTonder,
|
|
292
|
-
this.abortController.signal
|
|
293
|
-
);
|
|
294
|
-
return this.merchantData
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
async getCustomer(customer, signal) {
|
|
298
|
-
return await customerRegister(this.baseUrl, this.apiKeyTonder, customer, signal);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
132
|
async #mountAPMs() {
|
|
302
133
|
try{
|
|
303
|
-
const apms = await
|
|
134
|
+
const apms = await fetchCustomerAPMs(this.baseUrl, this.apiKeyTonder);
|
|
304
135
|
if(apms && apms['results'] && apms['results'].length > 0){
|
|
305
136
|
this.apmsData = apms['results']
|
|
306
137
|
this.#loadAPMList(apms['results'])
|
|
@@ -310,19 +141,23 @@ export class InlineCheckout {
|
|
|
310
141
|
}
|
|
311
142
|
}
|
|
312
143
|
|
|
313
|
-
async #mountTonder(getCards =
|
|
144
|
+
async #mountTonder(getCards = true) {
|
|
314
145
|
this.#mountPayButton()
|
|
146
|
+
await this._initializeCheckout()
|
|
315
147
|
try {
|
|
316
148
|
const {
|
|
317
149
|
vault_id,
|
|
318
|
-
vault_url
|
|
319
|
-
|
|
320
|
-
} = await this.#fetchMerchantData();
|
|
150
|
+
vault_url
|
|
151
|
+
} = this.merchantData;
|
|
321
152
|
if (this.email && getCards) {
|
|
322
|
-
const customerResponse = await this.
|
|
153
|
+
const customerResponse = await this._getCustomer({ email: this.email });
|
|
323
154
|
if ("auth_token" in customerResponse) {
|
|
324
155
|
const { auth_token } = customerResponse
|
|
325
|
-
const cards = await
|
|
156
|
+
const cards = await fetchCustomerCards(
|
|
157
|
+
this.baseUrl,
|
|
158
|
+
auth_token,
|
|
159
|
+
this.merchantData.business.pk
|
|
160
|
+
);
|
|
326
161
|
|
|
327
162
|
if ("cards" in cards) {
|
|
328
163
|
const cardsMapped = cards.cards.map(mapCards)
|
|
@@ -330,9 +165,6 @@ export class InlineCheckout {
|
|
|
330
165
|
}
|
|
331
166
|
}
|
|
332
167
|
}
|
|
333
|
-
if (!!mercado_pago && !!mercado_pago.active){
|
|
334
|
-
injectMercadoPagoSecurity()
|
|
335
|
-
}
|
|
336
168
|
|
|
337
169
|
await this.#mountAPMs();
|
|
338
170
|
|
|
@@ -380,16 +212,14 @@ export class InlineCheckout {
|
|
|
380
212
|
}
|
|
381
213
|
}
|
|
382
214
|
|
|
383
|
-
async
|
|
215
|
+
async _checkout() {
|
|
384
216
|
try {
|
|
385
217
|
document.querySelector("#tonderPayButton").disabled = true;
|
|
386
218
|
} catch (error) {
|
|
387
219
|
}
|
|
220
|
+
const { business } = this.merchantData
|
|
221
|
+
let cardTokens;
|
|
388
222
|
|
|
389
|
-
const { openpay_keys, reference, business } = this.merchantData
|
|
390
|
-
const total = Number(this.cartTotal)
|
|
391
|
-
|
|
392
|
-
let cardTokens = null;
|
|
393
223
|
if (this.radioChecked === "new" || this.radioChecked === undefined) {
|
|
394
224
|
cardTokens = await this.#getCardTokens();
|
|
395
225
|
} else {
|
|
@@ -398,107 +228,47 @@ export class InlineCheckout {
|
|
|
398
228
|
}
|
|
399
229
|
}
|
|
400
230
|
try {
|
|
401
|
-
|
|
402
|
-
if (openpay_keys.merchant_id && openpay_keys.public_key) {
|
|
403
|
-
deviceSessionIdTonder = await getOpenpayDeviceSessionID(
|
|
404
|
-
openpay_keys.merchant_id,
|
|
405
|
-
openpay_keys.public_key,
|
|
406
|
-
this.abortController.signal
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const { id, auth_token } = await this.getCustomer(
|
|
231
|
+
const customerData = await this._getCustomer(
|
|
411
232
|
this.customer,
|
|
412
233
|
this.abortController.signal
|
|
413
234
|
)
|
|
235
|
+
const { auth_token } = customerData;
|
|
414
236
|
if (auth_token && this.email) {
|
|
415
237
|
const saveCard = document.getElementById("save-checkout-card");
|
|
416
238
|
if (saveCard && "checked" in saveCard && saveCard.checked) {
|
|
417
|
-
|
|
239
|
+
try {
|
|
240
|
+
await saveCustomerCard(this.baseUrl, auth_token, business.pk, {
|
|
241
|
+
skyflow_id: cardTokens.skyflow_id,
|
|
242
|
+
});
|
|
243
|
+
showMessage("Tarjeta registrada con éxito", this.collectorIds.msgNotification);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
if (error?.message) {
|
|
246
|
+
showError(error.message)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
418
249
|
|
|
419
250
|
this.cardsInjected = false;
|
|
420
251
|
|
|
421
|
-
const cards = await
|
|
252
|
+
const cards = await fetchCustomerCards(
|
|
253
|
+
this.baseUrl,
|
|
254
|
+
auth_token,
|
|
255
|
+
this.merchantData.business.pk,
|
|
256
|
+
);
|
|
422
257
|
if ("cards" in cards) {
|
|
423
258
|
const cardsMapped = cards.cards.map((card) => mapCards(card))
|
|
424
259
|
this.#loadCardsList(cardsMapped, auth_token)
|
|
425
260
|
}
|
|
426
|
-
|
|
427
|
-
showMessage("Tarjeta registrada con éxito", this.collectorIds.msgNotification);
|
|
428
|
-
|
|
429
261
|
}
|
|
430
262
|
}
|
|
431
|
-
var orderItems = {
|
|
432
|
-
business: this.apiKeyTonder,
|
|
433
|
-
client: auth_token,
|
|
434
|
-
billing_address_id: null,
|
|
435
|
-
shipping_address_id: null,
|
|
436
|
-
amount: total,
|
|
437
|
-
status: "A",
|
|
438
|
-
reference: reference,
|
|
439
|
-
is_oneclick: true,
|
|
440
|
-
items: this.cartItems,
|
|
441
|
-
};
|
|
442
|
-
const jsonResponseOrder = await createOrder(
|
|
443
|
-
this.baseUrl,
|
|
444
|
-
this.apiKeyTonder,
|
|
445
|
-
orderItems
|
|
446
|
-
);
|
|
447
|
-
|
|
448
|
-
// Create payment
|
|
449
|
-
const now = new Date();
|
|
450
|
-
const dateString = now.toISOString();
|
|
451
|
-
|
|
452
|
-
var paymentItems = {
|
|
453
|
-
business_pk: business.pk,
|
|
454
|
-
client_id: id,
|
|
455
|
-
amount: total,
|
|
456
|
-
date: dateString,
|
|
457
|
-
order_id: jsonResponseOrder.id,
|
|
458
|
-
};
|
|
459
|
-
const jsonResponsePayment = await createPayment(
|
|
460
|
-
this.baseUrl,
|
|
461
|
-
this.apiKeyTonder,
|
|
462
|
-
paymentItems
|
|
463
|
-
);
|
|
464
263
|
|
|
465
264
|
const selected_apm = this.apmsData ? this.apmsData.find((iapm) => iapm.pk === this.radioChecked):{};
|
|
466
|
-
|
|
467
|
-
// Checkout router
|
|
468
|
-
const routerItems = {
|
|
469
|
-
name: this.firstName || "",
|
|
470
|
-
last_name: this.lastName || "",
|
|
471
|
-
email_client: this.email,
|
|
472
|
-
phone_number: this.phone,
|
|
473
|
-
return_url: this.returnUrl,
|
|
474
|
-
id_product: "no_id",
|
|
475
|
-
quantity_product: 1,
|
|
476
|
-
id_ship: "0",
|
|
477
|
-
instance_id_ship: "0",
|
|
478
|
-
amount: total,
|
|
479
|
-
title_ship: "shipping",
|
|
480
|
-
description: "transaction",
|
|
481
|
-
device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
|
|
482
|
-
token_id: "",
|
|
483
|
-
order_id: jsonResponseOrder.id,
|
|
484
|
-
business_id: business.pk,
|
|
485
|
-
payment_id: jsonResponsePayment.pk,
|
|
486
|
-
source: 'sdk',
|
|
487
|
-
metadata: this.metadata,
|
|
488
|
-
browser_info: getBrowserInfo(),
|
|
489
|
-
currency: this.currency,
|
|
490
|
-
...( selected_apm && Object.keys(selected_apm).length > 0
|
|
491
|
-
? {payment_method: selected_apm.payment_method}
|
|
492
|
-
: {card: cardTokens}
|
|
493
|
-
),
|
|
494
|
-
...(typeof MP_DEVICE_SESSION_ID !== "undefined" ? {mp_device_session_id: MP_DEVICE_SESSION_ID}:{})
|
|
495
|
-
};
|
|
496
265
|
|
|
497
|
-
const jsonResponseRouter = await
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
266
|
+
const jsonResponseRouter = await this._handleCheckout({
|
|
267
|
+
...( selected_apm && Object.keys(selected_apm).length > 0
|
|
268
|
+
? {payment_method: selected_apm.payment_method}
|
|
269
|
+
: {card: cardTokens}),
|
|
270
|
+
customer: customerData
|
|
271
|
+
});
|
|
502
272
|
|
|
503
273
|
if (jsonResponseRouter) {
|
|
504
274
|
try {
|
|
@@ -559,6 +329,7 @@ export class InlineCheckout {
|
|
|
559
329
|
for (const cardButton of cardsButtons) {
|
|
560
330
|
cardButton.addEventListener("click", (event) => {
|
|
561
331
|
event.preventDefault();
|
|
332
|
+
event.stopImmediatePropagation();
|
|
562
333
|
this.#handleDeleteCardButtonClick(token, cardButton)
|
|
563
334
|
}, false);
|
|
564
335
|
}
|
|
@@ -596,7 +367,8 @@ export class InlineCheckout {
|
|
|
596
367
|
this.abortRefreshCardsController.abort();
|
|
597
368
|
this.abortRefreshCardsController = new AbortController();
|
|
598
369
|
}
|
|
599
|
-
|
|
370
|
+
const businessId = this.merchantData.business.pk
|
|
371
|
+
await removeCustomerCard(this.baseUrl, customerToken, skyflow_id, businessId)
|
|
600
372
|
} catch {
|
|
601
373
|
} finally {
|
|
602
374
|
this.deletingCards = this.deletingCards.filter(id => id !== skyflow_id);
|
|
@@ -607,7 +379,12 @@ export class InlineCheckout {
|
|
|
607
379
|
async #refreshCardOnDelete(customerToken) {
|
|
608
380
|
if (this.deletingCards.length > 0) return;
|
|
609
381
|
this.cardsInjected = false
|
|
610
|
-
const cards = await
|
|
382
|
+
const cards = await fetchCustomerCards(
|
|
383
|
+
this.baseUrl,
|
|
384
|
+
customerToken,
|
|
385
|
+
this.merchantData.business.pk,
|
|
386
|
+
this.abortRefreshCardsController.signal
|
|
387
|
+
)
|
|
611
388
|
if ("cards" in cards) {
|
|
612
389
|
const cardsMapped = cards.cards.map(mapCards)
|
|
613
390
|
this.#loadCardsList(cardsMapped, customerToken)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildErrorResponse,
|
|
3
|
+
buildErrorResponseFromCatch,
|
|
4
|
+
} from "../helpers/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fetches Alternative Payment Methods (APMs) of a customer.
|
|
8
|
+
* @param {string} baseUrl - The base URL of the API.
|
|
9
|
+
* @param {string} apiKey - The API key for authentication.
|
|
10
|
+
* @param params - The query params to filter APMs
|
|
11
|
+
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
12
|
+
* @returns {Promise<Object>} The available APMs.
|
|
13
|
+
*/
|
|
14
|
+
export async function fetchCustomerAPMs(
|
|
15
|
+
baseUrl,
|
|
16
|
+
apiKey,
|
|
17
|
+
params = {
|
|
18
|
+
status: "active",
|
|
19
|
+
pagesize: "10000",
|
|
20
|
+
},
|
|
21
|
+
signal = null,
|
|
22
|
+
) {
|
|
23
|
+
try {
|
|
24
|
+
const queryString = new URLSearchParams(params).toString();
|
|
25
|
+
|
|
26
|
+
const response = await fetch(
|
|
27
|
+
`${baseUrl}/api/v1/payment_methods?${queryString}`,
|
|
28
|
+
{
|
|
29
|
+
method: "GET",
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: `Token ${apiKey}`,
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
},
|
|
34
|
+
signal,
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
if (response.ok) return await response.json();
|
|
39
|
+
const res_json = await response.json();
|
|
40
|
+
throw await buildErrorResponse(response, res_json);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
throw buildErrorResponseFromCatch(error);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches business information.
|
|
3
|
+
* @param {string} baseUrl - The base URL of the Tonder API.
|
|
4
|
+
* @param {string} apiKey - The API key for authentication.
|
|
5
|
+
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
6
|
+
* @returns {Promise<Object>} The business information.
|
|
7
|
+
*/
|
|
8
|
+
export async function fetchBusiness(baseUrl, apiKey, signal) {
|
|
9
|
+
const getBusiness = await fetch(
|
|
10
|
+
`${baseUrl}/api/v1/payments/business/${apiKey}`,
|
|
11
|
+
{
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: `Token ${apiKey}`,
|
|
14
|
+
},
|
|
15
|
+
signal: signal,
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
return await getBusiness.json();
|
|
19
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildErrorResponse,
|
|
3
|
+
buildErrorResponseFromCatch,
|
|
4
|
+
} from "../helpers/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Saves/Update a customer's card information.
|
|
8
|
+
* @param {string} baseUrl - The base URL of the API.
|
|
9
|
+
* @param {string} customerToken - The customer's authentication token.
|
|
10
|
+
* @param {string} businessId - The business ID.
|
|
11
|
+
* @param {Object} data - The card information to be saved.
|
|
12
|
+
* @returns {Promise<Object>} The saved card data.
|
|
13
|
+
*/
|
|
14
|
+
export async function saveCustomerCard(
|
|
15
|
+
baseUrl,
|
|
16
|
+
customerToken,
|
|
17
|
+
businessId,
|
|
18
|
+
data,
|
|
19
|
+
) {
|
|
20
|
+
try {
|
|
21
|
+
const url = `${baseUrl}/api/v1/business/${businessId}/cards/`;
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: {
|
|
25
|
+
Authorization: `Token ${customerToken}`,
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
},
|
|
28
|
+
body: JSON.stringify(data),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (response.ok) return await response.json();
|
|
32
|
+
|
|
33
|
+
const res_json = await response.json();
|
|
34
|
+
|
|
35
|
+
if (response.status === 409) {
|
|
36
|
+
if ((res_json.error = "Card number already exists.")) {
|
|
37
|
+
return {
|
|
38
|
+
code: 200,
|
|
39
|
+
body: res_json,
|
|
40
|
+
name: "",
|
|
41
|
+
message: res_json.error,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
throw await buildErrorResponse(response, res_json);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
throw buildErrorResponseFromCatch(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Removes a customer's card.
|
|
53
|
+
* @param {string} baseUrl - The base URL of the API.
|
|
54
|
+
* @param {string} customerToken - The customer's authentication token.
|
|
55
|
+
* @param {string} skyflowId - The Skyflow ID of the card to be removed.
|
|
56
|
+
* @param {string} businessId - The business ID.
|
|
57
|
+
* @returns {Promise<Object>} The result of the card removal operation.
|
|
58
|
+
*/
|
|
59
|
+
export async function removeCustomerCard(
|
|
60
|
+
baseUrl,
|
|
61
|
+
customerToken,
|
|
62
|
+
skyflowId = "",
|
|
63
|
+
businessId,
|
|
64
|
+
) {
|
|
65
|
+
try {
|
|
66
|
+
const url = `${baseUrl}/api/v1/business/${businessId}/cards/${skyflowId}`;
|
|
67
|
+
|
|
68
|
+
const response = await fetch(url, {
|
|
69
|
+
method: "DELETE",
|
|
70
|
+
headers: {
|
|
71
|
+
Authorization: `Token ${customerToken}`,
|
|
72
|
+
"Content-Type": "application/json",
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (response.ok) return await response.json();
|
|
77
|
+
const res_json = await response.json();
|
|
78
|
+
|
|
79
|
+
throw await buildErrorResponse(response, res_json);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
throw buildErrorResponseFromCatch(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Fetches a customer's saved cards.
|
|
87
|
+
* @param {string} baseUrl - The base URL of the API.
|
|
88
|
+
* @param {string} customerToken - The customer's authentication token.
|
|
89
|
+
* @param {string} businessId - The business ID.
|
|
90
|
+
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
91
|
+
* @returns {Promise<Object>} The customer's saved cards.
|
|
92
|
+
*/
|
|
93
|
+
export async function fetchCustomerCards(
|
|
94
|
+
baseUrl,
|
|
95
|
+
customerToken,
|
|
96
|
+
businessId,
|
|
97
|
+
signal= null,
|
|
98
|
+
) {
|
|
99
|
+
try {
|
|
100
|
+
const url = `${baseUrl}/api/v1/business/${businessId}/cards/`;
|
|
101
|
+
const response = await fetch(url, {
|
|
102
|
+
method: "GET",
|
|
103
|
+
headers: {
|
|
104
|
+
Authorization: `Token ${customerToken}`,
|
|
105
|
+
"Content-Type": "application/json",
|
|
106
|
+
},
|
|
107
|
+
signal,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (response.ok) return await response.json();
|
|
111
|
+
const res_json = await response.json();
|
|
112
|
+
throw await buildErrorResponse(response, res_json);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw buildErrorResponseFromCatch(error);
|
|
115
|
+
}
|
|
116
|
+
}
|