tonder-web-sdk 1.11.11 → 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 +64 -280
- 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 +81 -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,30 +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
|
-
|
|
5
|
-
|
|
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,
|
|
3
|
+
clearSpace,
|
|
4
|
+
injectMercadoPagoSecurity,
|
|
18
5
|
mapCards,
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
showError,
|
|
7
|
+
showMessage
|
|
21
8
|
} from '../helpers/utils';
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
|
|
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";
|
|
26
18
|
|
|
27
|
-
export class InlineCheckout {
|
|
19
|
+
export class InlineCheckout extends BaseInlineCheckout{
|
|
28
20
|
static injected = false;
|
|
29
21
|
static cardsInjected = false
|
|
30
22
|
static apmsInjected = false
|
|
@@ -32,7 +24,6 @@ export class InlineCheckout {
|
|
|
32
24
|
deletingCards = [];
|
|
33
25
|
customer = {}
|
|
34
26
|
items = []
|
|
35
|
-
baseUrl = null
|
|
36
27
|
collectContainer = null
|
|
37
28
|
merchantData = {}
|
|
38
29
|
cartTotal = null
|
|
@@ -55,36 +46,14 @@ export class InlineCheckout {
|
|
|
55
46
|
mode = "stage",
|
|
56
47
|
apiKey,
|
|
57
48
|
returnUrl,
|
|
58
|
-
successUrl,
|
|
59
49
|
renderPaymentButton = false,
|
|
60
50
|
callBack = () => { },
|
|
61
51
|
styles
|
|
62
52
|
}) {
|
|
63
|
-
|
|
64
|
-
this.returnUrl = returnUrl;
|
|
65
|
-
this.successUrl = successUrl;
|
|
53
|
+
super({ mode, apiKey, returnUrl, callBack });
|
|
66
54
|
this.renderPaymentButton = renderPaymentButton;
|
|
67
|
-
this.callBack = callBack;
|
|
68
55
|
this.customStyles = styles
|
|
69
|
-
this.mode = mode
|
|
70
|
-
this.baseUrl = this.#getBaseUrl()
|
|
71
|
-
|
|
72
|
-
this.abortController = new AbortController()
|
|
73
56
|
this.abortRefreshCardsController = new AbortController()
|
|
74
|
-
this.process3ds = new ThreeDSHandler(
|
|
75
|
-
{ apiKey: apiKey, baseUrl: this.baseUrl, successUrl: successUrl }
|
|
76
|
-
)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
#getBaseUrl() {
|
|
80
|
-
const modeUrls = {
|
|
81
|
-
'production': 'https://app.tonder.io',
|
|
82
|
-
'sandbox': 'https://sandbox.tonder.io',
|
|
83
|
-
'stage': 'https://stage.tonder.io',
|
|
84
|
-
'development': 'http://localhost:8000',
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return modeUrls[this.mode] || modeUrls['stage']
|
|
88
57
|
}
|
|
89
58
|
|
|
90
59
|
#mountPayButton() {
|
|
@@ -117,90 +86,7 @@ export class InlineCheckout {
|
|
|
117
86
|
}
|
|
118
87
|
}
|
|
119
88
|
|
|
120
|
-
|
|
121
|
-
const iframe = response?.next_action?.iframe_resources?.iframe
|
|
122
|
-
|
|
123
|
-
if (iframe) {
|
|
124
|
-
this.process3ds.loadIframe().then(() => {
|
|
125
|
-
//TODO: Check if this will be necessary on the frontend side
|
|
126
|
-
// after some the tests in production, since the 3DS process
|
|
127
|
-
// doesn't works properly on the sandbox environment
|
|
128
|
-
// setTimeout(() => {
|
|
129
|
-
// process3ds.verifyTransactionStatus();
|
|
130
|
-
// }, 10000);
|
|
131
|
-
this.process3ds.verifyTransactionStatus();
|
|
132
|
-
}).catch((error) => {
|
|
133
|
-
console.log('Error loading iframe:', error)
|
|
134
|
-
})
|
|
135
|
-
} else {
|
|
136
|
-
const redirectUrl = this.process3ds.getRedirectUrl()
|
|
137
|
-
if (redirectUrl) {
|
|
138
|
-
this.process3ds.redirectToChallenge()
|
|
139
|
-
} else {
|
|
140
|
-
return response;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
payment(data) {
|
|
146
|
-
return new Promise(async (resolve, reject) => {
|
|
147
|
-
try {
|
|
148
|
-
this.#handleCustomer(data.customer)
|
|
149
|
-
this.setCartTotal(data.cart?.total)
|
|
150
|
-
this.setCartItems(data.cart?.items)
|
|
151
|
-
this.#handleMetadata(data)
|
|
152
|
-
this.#handleCurrency(data)
|
|
153
|
-
this.#handleCard(data)
|
|
154
|
-
const response = await this.#checkout()
|
|
155
|
-
this.process3ds.setPayload(response)
|
|
156
|
-
this.callBack(response);
|
|
157
|
-
const payload = await this.handle3dsRedirect(response)
|
|
158
|
-
if (payload) {
|
|
159
|
-
resolve(response);
|
|
160
|
-
}
|
|
161
|
-
} catch (error) {
|
|
162
|
-
reject(error);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
#handleCustomer(customer) {
|
|
168
|
-
if (!customer) return
|
|
169
|
-
|
|
170
|
-
this.firstName = customer?.firstName
|
|
171
|
-
this.lastName = customer?.lastName
|
|
172
|
-
this.country = customer?.country
|
|
173
|
-
this.address = customer?.street
|
|
174
|
-
this.city = customer?.city
|
|
175
|
-
this.state = customer?.state
|
|
176
|
-
this.postCode = customer?.postCode
|
|
177
|
-
this.email = customer?.email
|
|
178
|
-
this.phone = customer?.phone
|
|
179
|
-
this.customer = customer
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
#handleMetadata(data) {
|
|
183
|
-
this.metadata = data?.metadata
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
#handleCurrency(data) {
|
|
187
|
-
this.currency = data?.currency
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
#handleCard(data) {
|
|
191
|
-
this.card = data?.card
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
setCartItems(items) {
|
|
195
|
-
this.cartItems = items
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
configureCheckout(data) {
|
|
199
|
-
if ('customer' in data)
|
|
200
|
-
this.#handleCustomer(data['customer'])
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
setCartTotal(total) {
|
|
89
|
+
_setCartTotal(total) {
|
|
204
90
|
this.cartTotal = total
|
|
205
91
|
this.#updatePayButton()
|
|
206
92
|
}
|
|
@@ -236,47 +122,6 @@ export class InlineCheckout {
|
|
|
236
122
|
});
|
|
237
123
|
}
|
|
238
124
|
|
|
239
|
-
async verify3dsTransaction () {
|
|
240
|
-
globalLoader.show()
|
|
241
|
-
const result3ds = await this.process3ds.verifyTransactionStatus()
|
|
242
|
-
const resultCheckout = await this.resumeCheckout(result3ds)
|
|
243
|
-
this.process3ds.setPayload(resultCheckout)
|
|
244
|
-
globalLoader.remove()
|
|
245
|
-
return this.handle3dsRedirect(resultCheckout)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
async resumeCheckout(response) {
|
|
250
|
-
// Stop the routing process if the transaction is either hard declined or successful
|
|
251
|
-
if (response?.decline?.error_type === "Hard") {
|
|
252
|
-
return response
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (["Success", "Authorized"].includes(response?.transaction_status)) {
|
|
256
|
-
return response;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (response) {
|
|
260
|
-
globalLoader.show()
|
|
261
|
-
const routerItems = {
|
|
262
|
-
checkout_id: response?.checkout?.id,
|
|
263
|
-
};
|
|
264
|
-
try {
|
|
265
|
-
const routerResponse = await startCheckoutRouter(
|
|
266
|
-
this.baseUrl,
|
|
267
|
-
this.apiKeyTonder,
|
|
268
|
-
routerItems
|
|
269
|
-
);
|
|
270
|
-
return routerResponse
|
|
271
|
-
} catch (error) {
|
|
272
|
-
// throw error
|
|
273
|
-
} finally {
|
|
274
|
-
globalLoader.remove()
|
|
275
|
-
}
|
|
276
|
-
return response
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
125
|
#mount(containerTonderCheckout) {
|
|
281
126
|
containerTonderCheckout.innerHTML = cardTemplate({renderPaymentButton: this.renderPaymentButton, customStyles: this.customStyles});
|
|
282
127
|
globalLoader.show()
|
|
@@ -284,22 +129,9 @@ export class InlineCheckout {
|
|
|
284
129
|
InlineCheckout.injected = true;
|
|
285
130
|
}
|
|
286
131
|
|
|
287
|
-
async #fetchMerchantData() {
|
|
288
|
-
this.merchantData = await getBusiness(
|
|
289
|
-
this.baseUrl,
|
|
290
|
-
this.apiKeyTonder,
|
|
291
|
-
this.abortController.signal
|
|
292
|
-
);
|
|
293
|
-
return this.merchantData
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
async getCustomer(customer, signal) {
|
|
297
|
-
return await customerRegister(this.baseUrl, this.apiKeyTonder, customer, signal);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
132
|
async #mountAPMs() {
|
|
301
133
|
try{
|
|
302
|
-
const apms = await
|
|
134
|
+
const apms = await fetchCustomerAPMs(this.baseUrl, this.apiKeyTonder);
|
|
303
135
|
if(apms && apms['results'] && apms['results'].length > 0){
|
|
304
136
|
this.apmsData = apms['results']
|
|
305
137
|
this.#loadAPMList(apms['results'])
|
|
@@ -309,18 +141,23 @@ export class InlineCheckout {
|
|
|
309
141
|
}
|
|
310
142
|
}
|
|
311
143
|
|
|
312
|
-
async #mountTonder(getCards =
|
|
144
|
+
async #mountTonder(getCards = true) {
|
|
313
145
|
this.#mountPayButton()
|
|
146
|
+
await this._initializeCheckout()
|
|
314
147
|
try {
|
|
315
148
|
const {
|
|
316
149
|
vault_id,
|
|
317
|
-
vault_url
|
|
318
|
-
} =
|
|
150
|
+
vault_url
|
|
151
|
+
} = this.merchantData;
|
|
319
152
|
if (this.email && getCards) {
|
|
320
|
-
const customerResponse = await this.
|
|
153
|
+
const customerResponse = await this._getCustomer({ email: this.email });
|
|
321
154
|
if ("auth_token" in customerResponse) {
|
|
322
155
|
const { auth_token } = customerResponse
|
|
323
|
-
const cards = await
|
|
156
|
+
const cards = await fetchCustomerCards(
|
|
157
|
+
this.baseUrl,
|
|
158
|
+
auth_token,
|
|
159
|
+
this.merchantData.business.pk
|
|
160
|
+
);
|
|
324
161
|
|
|
325
162
|
if ("cards" in cards) {
|
|
326
163
|
const cardsMapped = cards.cards.map(mapCards)
|
|
@@ -328,7 +165,7 @@ export class InlineCheckout {
|
|
|
328
165
|
}
|
|
329
166
|
}
|
|
330
167
|
}
|
|
331
|
-
|
|
168
|
+
|
|
332
169
|
await this.#mountAPMs();
|
|
333
170
|
|
|
334
171
|
this.collectContainer = await initSkyflow(
|
|
@@ -375,16 +212,14 @@ export class InlineCheckout {
|
|
|
375
212
|
}
|
|
376
213
|
}
|
|
377
214
|
|
|
378
|
-
async
|
|
215
|
+
async _checkout() {
|
|
379
216
|
try {
|
|
380
217
|
document.querySelector("#tonderPayButton").disabled = true;
|
|
381
218
|
} catch (error) {
|
|
382
219
|
}
|
|
220
|
+
const { business } = this.merchantData
|
|
221
|
+
let cardTokens;
|
|
383
222
|
|
|
384
|
-
const { openpay_keys, reference, business } = this.merchantData
|
|
385
|
-
const total = Number(this.cartTotal)
|
|
386
|
-
|
|
387
|
-
let cardTokens = null;
|
|
388
223
|
if (this.radioChecked === "new" || this.radioChecked === undefined) {
|
|
389
224
|
cardTokens = await this.#getCardTokens();
|
|
390
225
|
} else {
|
|
@@ -393,105 +228,47 @@ export class InlineCheckout {
|
|
|
393
228
|
}
|
|
394
229
|
}
|
|
395
230
|
try {
|
|
396
|
-
|
|
397
|
-
if (openpay_keys.merchant_id && openpay_keys.public_key) {
|
|
398
|
-
deviceSessionIdTonder = await getOpenpayDeviceSessionID(
|
|
399
|
-
openpay_keys.merchant_id,
|
|
400
|
-
openpay_keys.public_key,
|
|
401
|
-
this.abortController.signal
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const { id, auth_token } = await this.getCustomer(
|
|
231
|
+
const customerData = await this._getCustomer(
|
|
406
232
|
this.customer,
|
|
407
233
|
this.abortController.signal
|
|
408
234
|
)
|
|
235
|
+
const { auth_token } = customerData;
|
|
409
236
|
if (auth_token && this.email) {
|
|
410
237
|
const saveCard = document.getElementById("save-checkout-card");
|
|
411
238
|
if (saveCard && "checked" in saveCard && saveCard.checked) {
|
|
412
|
-
|
|
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
|
+
}
|
|
413
249
|
|
|
414
250
|
this.cardsInjected = false;
|
|
415
251
|
|
|
416
|
-
const cards = await
|
|
252
|
+
const cards = await fetchCustomerCards(
|
|
253
|
+
this.baseUrl,
|
|
254
|
+
auth_token,
|
|
255
|
+
this.merchantData.business.pk,
|
|
256
|
+
);
|
|
417
257
|
if ("cards" in cards) {
|
|
418
258
|
const cardsMapped = cards.cards.map((card) => mapCards(card))
|
|
419
259
|
this.#loadCardsList(cardsMapped, auth_token)
|
|
420
260
|
}
|
|
421
|
-
|
|
422
|
-
showMessage("Tarjeta registrada con éxito", this.collectorIds.msgNotification);
|
|
423
|
-
|
|
424
261
|
}
|
|
425
262
|
}
|
|
426
|
-
var orderItems = {
|
|
427
|
-
business: this.apiKeyTonder,
|
|
428
|
-
client: auth_token,
|
|
429
|
-
billing_address_id: null,
|
|
430
|
-
shipping_address_id: null,
|
|
431
|
-
amount: total,
|
|
432
|
-
status: "A",
|
|
433
|
-
reference: reference,
|
|
434
|
-
is_oneclick: true,
|
|
435
|
-
items: this.cartItems,
|
|
436
|
-
};
|
|
437
|
-
const jsonResponseOrder = await createOrder(
|
|
438
|
-
this.baseUrl,
|
|
439
|
-
this.apiKeyTonder,
|
|
440
|
-
orderItems
|
|
441
|
-
);
|
|
442
|
-
|
|
443
|
-
// Create payment
|
|
444
|
-
const now = new Date();
|
|
445
|
-
const dateString = now.toISOString();
|
|
446
|
-
|
|
447
|
-
var paymentItems = {
|
|
448
|
-
business_pk: business.pk,
|
|
449
|
-
client_id: id,
|
|
450
|
-
amount: total,
|
|
451
|
-
date: dateString,
|
|
452
|
-
order_id: jsonResponseOrder.id,
|
|
453
|
-
};
|
|
454
|
-
const jsonResponsePayment = await createPayment(
|
|
455
|
-
this.baseUrl,
|
|
456
|
-
this.apiKeyTonder,
|
|
457
|
-
paymentItems
|
|
458
|
-
);
|
|
459
263
|
|
|
460
264
|
const selected_apm = this.apmsData ? this.apmsData.find((iapm) => iapm.pk === this.radioChecked):{};
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const routerItems = {
|
|
464
|
-
name: this.firstName || "",
|
|
465
|
-
last_name: this.lastName || "",
|
|
466
|
-
email_client: this.email,
|
|
467
|
-
phone_number: this.phone,
|
|
468
|
-
return_url: this.returnUrl,
|
|
469
|
-
id_product: "no_id",
|
|
470
|
-
quantity_product: 1,
|
|
471
|
-
id_ship: "0",
|
|
472
|
-
instance_id_ship: "0",
|
|
473
|
-
amount: total,
|
|
474
|
-
title_ship: "shipping",
|
|
475
|
-
description: "transaction",
|
|
476
|
-
device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
|
|
477
|
-
token_id: "",
|
|
478
|
-
order_id: jsonResponseOrder.id,
|
|
479
|
-
business_id: business.pk,
|
|
480
|
-
payment_id: jsonResponsePayment.pk,
|
|
481
|
-
source: 'sdk',
|
|
482
|
-
metadata: this.metadata,
|
|
483
|
-
browser_info: getBrowserInfo(),
|
|
484
|
-
currency: this.currency,
|
|
265
|
+
|
|
266
|
+
const jsonResponseRouter = await this._handleCheckout({
|
|
485
267
|
...( selected_apm && Object.keys(selected_apm).length > 0
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
};
|
|
490
|
-
const jsonResponseRouter = await startCheckoutRouter(
|
|
491
|
-
this.baseUrl,
|
|
492
|
-
this.apiKeyTonder,
|
|
493
|
-
routerItems
|
|
494
|
-
);
|
|
268
|
+
? {payment_method: selected_apm.payment_method}
|
|
269
|
+
: {card: cardTokens}),
|
|
270
|
+
customer: customerData
|
|
271
|
+
});
|
|
495
272
|
|
|
496
273
|
if (jsonResponseRouter) {
|
|
497
274
|
try {
|
|
@@ -552,6 +329,7 @@ export class InlineCheckout {
|
|
|
552
329
|
for (const cardButton of cardsButtons) {
|
|
553
330
|
cardButton.addEventListener("click", (event) => {
|
|
554
331
|
event.preventDefault();
|
|
332
|
+
event.stopImmediatePropagation();
|
|
555
333
|
this.#handleDeleteCardButtonClick(token, cardButton)
|
|
556
334
|
}, false);
|
|
557
335
|
}
|
|
@@ -589,7 +367,8 @@ export class InlineCheckout {
|
|
|
589
367
|
this.abortRefreshCardsController.abort();
|
|
590
368
|
this.abortRefreshCardsController = new AbortController();
|
|
591
369
|
}
|
|
592
|
-
|
|
370
|
+
const businessId = this.merchantData.business.pk
|
|
371
|
+
await removeCustomerCard(this.baseUrl, customerToken, skyflow_id, businessId)
|
|
593
372
|
} catch {
|
|
594
373
|
} finally {
|
|
595
374
|
this.deletingCards = this.deletingCards.filter(id => id !== skyflow_id);
|
|
@@ -600,7 +379,12 @@ export class InlineCheckout {
|
|
|
600
379
|
async #refreshCardOnDelete(customerToken) {
|
|
601
380
|
if (this.deletingCards.length > 0) return;
|
|
602
381
|
this.cardsInjected = false
|
|
603
|
-
const cards = await
|
|
382
|
+
const cards = await fetchCustomerCards(
|
|
383
|
+
this.baseUrl,
|
|
384
|
+
customerToken,
|
|
385
|
+
this.merchantData.business.pk,
|
|
386
|
+
this.abortRefreshCardsController.signal
|
|
387
|
+
)
|
|
604
388
|
if ("cards" in cards) {
|
|
605
389
|
const cardsMapped = cards.cards.map(mapCards)
|
|
606
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
|
+
}
|