tonder-web-sdk 1.15.2 → 1.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -25
- package/package.json +2 -1
- package/src/classes/BaseInlineCheckout.js +13 -7
- package/src/classes/LiteInlineCheckout.js +3 -0
- package/src/classes/inlineCheckout.js +90 -10
- package/src/helpers/skyflow.js +121 -39
- package/src/helpers/template.js +103 -21
- package/src/index-dev.js +8 -3
- package/types/common.d.ts +2 -1
- package/v1/bundle.min.js +3 -3
package/src/helpers/skyflow.js
CHANGED
|
@@ -11,18 +11,7 @@ export async function initSkyflow(
|
|
|
11
11
|
customStyles = {},
|
|
12
12
|
collectorIds,
|
|
13
13
|
) {
|
|
14
|
-
const skyflow = await
|
|
15
|
-
vaultID: vaultId,
|
|
16
|
-
vaultURL: vaultUrl,
|
|
17
|
-
getBearerToken: async () => {
|
|
18
|
-
// Pass the signal to the fetch call
|
|
19
|
-
return await getVaultToken(baseUrl, apiKey, signal)
|
|
20
|
-
},
|
|
21
|
-
options: {
|
|
22
|
-
logLevel: Skyflow.LogLevel.ERROR,
|
|
23
|
-
env: Skyflow.Env.DEV,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
14
|
+
const skyflow = await initializeSkyflow(vaultId, vaultUrl, baseUrl, apiKey, signal);
|
|
26
15
|
|
|
27
16
|
// Create collect Container.
|
|
28
17
|
const collectContainer = await skyflow.container(
|
|
@@ -41,15 +30,8 @@ export async function initSkyflow(
|
|
|
41
30
|
max: 70,
|
|
42
31
|
},
|
|
43
32
|
};
|
|
44
|
-
const regexEmpty = RegExp("^(?!\s*$).+");
|
|
45
33
|
|
|
46
|
-
|
|
47
|
-
type: Skyflow.ValidationRuleType.REGEX_MATCH_RULE,
|
|
48
|
-
params: {
|
|
49
|
-
regex: regexEmpty,
|
|
50
|
-
error: "El campo es requerido" // Optional, default error is 'VALIDATION FAILED'.
|
|
51
|
-
}
|
|
52
|
-
}
|
|
34
|
+
|
|
53
35
|
|
|
54
36
|
const cardHolderNameElement = await collectContainer.create({
|
|
55
37
|
table: "cards",
|
|
@@ -136,13 +118,31 @@ export async function initSkyflow(
|
|
|
136
118
|
collectStylesOptions.errorTextStyles
|
|
137
119
|
);
|
|
138
120
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
121
|
+
|
|
122
|
+
const elementsConfig = {
|
|
123
|
+
cardNumber: {
|
|
124
|
+
element: cardNumberElement,
|
|
125
|
+
container: "#collectCardNumber",
|
|
126
|
+
},
|
|
127
|
+
cvv: {
|
|
128
|
+
element: cvvElement,
|
|
129
|
+
container: "#collectCvv",
|
|
130
|
+
},
|
|
131
|
+
expiryMonth: {
|
|
132
|
+
element: expiryMonthElement,
|
|
133
|
+
container: "#collectExpirationMonth",
|
|
134
|
+
},
|
|
135
|
+
expiryYear: {
|
|
136
|
+
element: expiryYearElement,
|
|
137
|
+
container: "#collectExpirationYear",
|
|
138
|
+
},
|
|
139
|
+
cardHolderName: {
|
|
140
|
+
element: cardHolderNameElement,
|
|
141
|
+
container: "#collectCardholderName",
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
await mountElements(elementsConfig)
|
|
146
146
|
|
|
147
147
|
return {
|
|
148
148
|
container: collectContainer,
|
|
@@ -156,21 +156,93 @@ export async function initSkyflow(
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
|
|
160
|
+
export async function initUpdateSkyflow(
|
|
161
|
+
skyflowId,
|
|
162
|
+
vaultId,
|
|
163
|
+
vaultUrl,
|
|
164
|
+
baseUrl,
|
|
165
|
+
apiKey,
|
|
166
|
+
signal,
|
|
167
|
+
customStyles = {},
|
|
168
|
+
){
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
const skyflow = await initializeSkyflow(vaultId, vaultUrl, baseUrl, apiKey, signal);
|
|
172
|
+
|
|
173
|
+
var collectStylesOptions = Object.keys(customStyles).length === 0 ? defaultStyles : customStyles
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
// Create collect Container.
|
|
177
|
+
const collectContainer = await skyflow.container(
|
|
178
|
+
Skyflow.ContainerType.COLLECT
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const cvvElement = await collectContainer.create({
|
|
182
|
+
table: "cards",
|
|
183
|
+
column: "cvv",
|
|
184
|
+
...collectStylesOptions,
|
|
185
|
+
label: collectStylesOptions.labels?.cvvLabel,
|
|
186
|
+
placeholder: collectStylesOptions.placeholders?.cvvPlaceholder,
|
|
187
|
+
type: Skyflow.ElementType.CVV,
|
|
188
|
+
validations: [regexMatchRule],
|
|
189
|
+
skyflowID: skyflowId
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
handleSkyflowElementEvents(
|
|
193
|
+
cvvElement,
|
|
194
|
+
"",
|
|
195
|
+
collectStylesOptions.errorTextStyles
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const elementsConfig = {
|
|
199
|
+
cvv: {
|
|
200
|
+
element: cvvElement,
|
|
201
|
+
container: `#collectCvv${skyflowId}`,
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
await mountElements(elementsConfig)
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
container: collectContainer,
|
|
208
|
+
elements: {
|
|
209
|
+
cvvElement,
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function initializeSkyflow(vaultId, vaultUrl, baseUrl, apiKey, signal){
|
|
215
|
+
return await Skyflow.init({
|
|
216
|
+
vaultID: vaultId,
|
|
217
|
+
vaultURL: vaultUrl,
|
|
218
|
+
getBearerToken: async () => {
|
|
219
|
+
// Pass the signal to the fetch call
|
|
220
|
+
return await getVaultToken(baseUrl, apiKey, signal)
|
|
221
|
+
},
|
|
222
|
+
options: {
|
|
223
|
+
logLevel: Skyflow.LogLevel.ERROR,
|
|
224
|
+
env: Skyflow.Env.DEV,
|
|
225
|
+
},
|
|
226
|
+
});
|
|
171
227
|
}
|
|
172
228
|
|
|
173
229
|
|
|
230
|
+
async function mountElements(elementsConfig) {
|
|
231
|
+
if (typeof elementsConfig !== "object" || elementsConfig === null) {
|
|
232
|
+
throw new Error("Invalid configuration object");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
for (const [elementKey, { element, container }] of Object.entries(elementsConfig)) {
|
|
236
|
+
if (element && container) {
|
|
237
|
+
element.mount(container);
|
|
238
|
+
} else {
|
|
239
|
+
console.warn(
|
|
240
|
+
`Skipping mount for '${elementKey}' due to missing element or container.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
174
246
|
function handleSkyflowElementEvents(element, fieldMessage= "", error_styles = {}, resetOnFocus = true, requiredMessage = "El campo es requerido", invalidMessage= "El campo es inválido") {
|
|
175
247
|
if ("on" in element) {
|
|
176
248
|
element.on(Skyflow.EventName.CHANGE, (state) => {
|
|
@@ -277,3 +349,13 @@ async function getFields(data, collectContainer) {
|
|
|
277
349
|
)
|
|
278
350
|
}
|
|
279
351
|
|
|
352
|
+
const regexEmpty = RegExp("^(?!\s*$).+");
|
|
353
|
+
const regexMatchRule = {
|
|
354
|
+
type: Skyflow.ValidationRuleType.REGEX_MATCH_RULE,
|
|
355
|
+
params: {
|
|
356
|
+
regex: regexEmpty,
|
|
357
|
+
error: "El campo es requerido" // Optional, default error is 'VALIDATION FAILED'.
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
|
package/src/helpers/template.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "accordion-js/dist/accordion.min.css";
|
|
1
2
|
import { getCardType } from "./utils";
|
|
2
3
|
import {getPaymentMethodDetails} from "../shared/catalog/paymentMethodsCatalog";
|
|
3
4
|
|
|
@@ -39,7 +40,7 @@ export const cardTemplate = (data) => `
|
|
|
39
40
|
</div>
|
|
40
41
|
<div id="apmsListContainer" class="apms-list-container"></div>
|
|
41
42
|
<div class="container-pay-button">
|
|
42
|
-
<button id="tonderPayButton" class="pay-button">Pagar</button>
|
|
43
|
+
<button id="tonderPayButton" class="pay-button hidden">Pagar</button>
|
|
43
44
|
</div>
|
|
44
45
|
</div>
|
|
45
46
|
|
|
@@ -121,6 +122,8 @@ export const cardTemplate = (data) => `
|
|
|
121
122
|
background-color: #000;
|
|
122
123
|
color: #fff;
|
|
123
124
|
margin-bottom: 0px;
|
|
125
|
+
}
|
|
126
|
+
.hidden{
|
|
124
127
|
display: none;
|
|
125
128
|
}
|
|
126
129
|
|
|
@@ -335,29 +338,108 @@ export const cardTemplate = (data) => `
|
|
|
335
338
|
</style>
|
|
336
339
|
`
|
|
337
340
|
|
|
338
|
-
export const cardItemsTemplate = (cards) => {
|
|
339
|
-
|
|
341
|
+
export const cardItemsTemplate = (cards, data) => {
|
|
342
|
+
|
|
343
|
+
|
|
340
344
|
const cardItemsHTML = cards.reduce((total, card) => {
|
|
341
345
|
return `${total}
|
|
342
|
-
<div class="
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
<
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
346
|
+
<div class="ac" id="card_container-${card.skyflow_id}">
|
|
347
|
+
<div class="card-item" >
|
|
348
|
+
<input id="${card.skyflow_id}" class="card_selected" name="card_selected" type="radio"/>
|
|
349
|
+
<label class="card-item-label" for="${card.skyflow_id}">
|
|
350
|
+
<!-- <div class="ac-trigger">-->
|
|
351
|
+
<img class="card-image" src="${getCardType(card.card_scheme)}" />
|
|
352
|
+
<div class="card-number">${card.card_number}</div>
|
|
353
|
+
<div class="card-expiration">Exp. ${card.expiration_month}/${card.expiration_year}</div>
|
|
354
|
+
<!-- </div>-->
|
|
355
|
+
<div class="card-delete-icon">
|
|
356
|
+
<button id="delete_button_${card.skyflow_id}" class="card-delete-button">
|
|
357
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
|
|
358
|
+
<path fill="currentColor" d="M292.309-140.001q-30.308 0-51.308-21t-21-51.308V-720h-40v-59.999H360v-35.384h240v35.384h179.999V-720h-40v507.691q0 30.308-21 51.308t-51.308 21H292.309ZM376.155-280h59.999v-360h-59.999v360Zm147.691 0h59.999v-360h-59.999v360Z"/>
|
|
359
|
+
</svg>
|
|
360
|
+
</button>
|
|
361
|
+
</div>
|
|
362
|
+
</label>
|
|
363
|
+
</div>
|
|
364
|
+
<div class="ac-panel">
|
|
365
|
+
<div class="ac-card-panel-container" id="acContainer${card.skyflow_id}">
|
|
366
|
+
<div class="cvvContainer" id="cvvContainer${card.skyflow_id}">
|
|
367
|
+
<div id="collectCvv${card.skyflow_id}" class="empty-div"></div>
|
|
368
|
+
<svg class="cvvIcon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="24" viewBox="0 0 270 178">
|
|
369
|
+
<defs>
|
|
370
|
+
<linearGradient id="linear-gradient" x1="0.5" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
|
|
371
|
+
<stop offset="0" stop-color="#386bbf"/>
|
|
372
|
+
<stop offset="1" stop-color="#032ea3"/>
|
|
373
|
+
</linearGradient>
|
|
374
|
+
<linearGradient id="linear-gradient-2" x1="0.5" y1="0.115" x2="0.5" y2="1" gradientUnits="objectBoundingBox">
|
|
375
|
+
<stop offset="0" stop-color="#1c1c1c"/>
|
|
376
|
+
<stop offset="1" stop-color="#151515"/>
|
|
377
|
+
</linearGradient>
|
|
378
|
+
</defs>
|
|
379
|
+
<g id="Grupo_3" data-name="Grupo 3" transform="translate(-69 -312)">
|
|
380
|
+
<g id="Grupo_2" data-name="Grupo 2">
|
|
381
|
+
<rect id="Rectángulo_58" data-name="Rectángulo 58" width="253" height="165" rx="25" transform="translate(69 312)" fill="url(#linear-gradient)"/>
|
|
382
|
+
<rect id="Rectángulo_61" data-name="Rectángulo 61" width="68" height="8" rx="4" transform="translate(86 437)" fill="#fff" opacity="0.877"/>
|
|
383
|
+
<rect id="Rectángulo_66" data-name="Rectángulo 66" width="253" height="24" transform="translate(69 347)" fill="url(#linear-gradient-2)"/>
|
|
384
|
+
<g id="Elipse_4" data-name="Elipse 4" transform="translate(221 374)" fill="#fff" stroke="#191919" stroke-width="1">
|
|
385
|
+
<ellipse cx="59" cy="58" rx="59" ry="58" stroke="none"/>
|
|
386
|
+
<ellipse cx="59" cy="58" rx="58.5" ry="57.5" fill="none"/>
|
|
387
|
+
</g>
|
|
388
|
+
</g>
|
|
389
|
+
<text id="_123" data-name="123" transform="translate(240 448)" font-size="45" font-family="Menlo-Regular, Menlo"><tspan x="0" y="0">123</tspan></text>
|
|
390
|
+
</g>
|
|
391
|
+
</svg>
|
|
392
|
+
</div>
|
|
393
|
+
${ data?.renderPaymentButton ?
|
|
394
|
+
`<div class="container-card-pay-button">
|
|
395
|
+
<button id="tonderPayButton${card.skyflow_id}" class="card-pay-button pay-button">Pagar</button>
|
|
396
|
+
</div> `
|
|
397
|
+
:``
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
356
402
|
</div>`
|
|
357
|
-
}, ``);
|
|
358
403
|
|
|
404
|
+
}, "");
|
|
359
405
|
const cardItemStyle = `
|
|
360
406
|
<style>
|
|
407
|
+
.ac {
|
|
408
|
+
background-color: transparent !important;
|
|
409
|
+
margin-bottom: 0 !important;
|
|
410
|
+
border-bottom: 1px solid #e2e8f0;
|
|
411
|
+
}
|
|
412
|
+
.ac-card-panel-container{
|
|
413
|
+
padding: ${data?.renderPaymentButton ? '20px 32px 0px 32px':'20px 32px 20px 32px'};
|
|
414
|
+
}
|
|
415
|
+
.cvvContainer{
|
|
416
|
+
max-width: 45%;
|
|
417
|
+
position: relative;
|
|
418
|
+
padding: 0px 28px 0px 28px;
|
|
419
|
+
}
|
|
420
|
+
.cvvIcon {
|
|
421
|
+
position: absolute;
|
|
422
|
+
right: 16%;
|
|
423
|
+
top: 43%;
|
|
424
|
+
opacity: 0;
|
|
425
|
+
transform: translateY(10px);
|
|
426
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
427
|
+
}
|
|
428
|
+
.cvvContainer.show .cvvIcon,
|
|
429
|
+
.ac-card-panel-container.show .card-pay-button {
|
|
430
|
+
opacity: 1;
|
|
431
|
+
transform: translateY(0);
|
|
432
|
+
transition-delay: 0.3s;
|
|
433
|
+
}
|
|
434
|
+
.container-card-pay-button{
|
|
435
|
+
margin: 20px 0px;
|
|
436
|
+
}
|
|
437
|
+
.card-pay-button{
|
|
438
|
+
display: block;
|
|
439
|
+
opacity: 0;
|
|
440
|
+
transform: translateY(10px);
|
|
441
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
442
|
+
}
|
|
361
443
|
.card-item-label {
|
|
362
444
|
display: flex;
|
|
363
445
|
justify-content: space-between;
|
|
@@ -368,14 +450,12 @@ export const cardItemsTemplate = (cards) => {
|
|
|
368
450
|
margin-bottom: 15px;
|
|
369
451
|
width: 100%;
|
|
370
452
|
}
|
|
371
|
-
|
|
372
453
|
.card-item {
|
|
373
454
|
position: relative;
|
|
374
455
|
display: flex;
|
|
375
456
|
justify-content: start;
|
|
376
457
|
align-items: center;
|
|
377
458
|
gap: 33% 15px;
|
|
378
|
-
border-bottom: 1px solid #e2e8f0;
|
|
379
459
|
padding: 0px 30px;
|
|
380
460
|
}
|
|
381
461
|
|
|
@@ -488,7 +568,9 @@ export const cardItemsTemplate = (cards) => {
|
|
|
488
568
|
</style>
|
|
489
569
|
`
|
|
490
570
|
const cardItem = `
|
|
491
|
-
|
|
571
|
+
<div class="accordion-container">
|
|
572
|
+
${cardItemsHTML}
|
|
573
|
+
</div>
|
|
492
574
|
${cardItemStyle}
|
|
493
575
|
`
|
|
494
576
|
return cardItem;
|
package/src/index-dev.js
CHANGED
|
@@ -135,8 +135,8 @@ function setupInlineCheckout() {
|
|
|
135
135
|
},
|
|
136
136
|
});
|
|
137
137
|
inlineCheckout.configureCheckout({
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
secureToken: "eyJhbGc...",
|
|
139
|
+
...checkoutData
|
|
140
140
|
});
|
|
141
141
|
inlineCheckout.injectCheckout();
|
|
142
142
|
// ['Declined', 'Cancelled', 'Failed', 'Success', 'Pending', 'Authorized']
|
|
@@ -167,7 +167,12 @@ function setupLiteInlineCheckout() {
|
|
|
167
167
|
customer: checkoutData.customer,
|
|
168
168
|
secureToken: "eyJhbGc..."
|
|
169
169
|
});
|
|
170
|
-
liteInlineCheckout.injectCheckout().then(() => {
|
|
170
|
+
liteInlineCheckout.injectCheckout().then(() => {
|
|
171
|
+
liteInlineCheckout.getCustomerCards().then((r) => {
|
|
172
|
+
console.log('customer cards', r)
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
171
176
|
liteInlineCheckout.verify3dsTransaction().then((response) => {
|
|
172
177
|
console.log("Verify 3ds response", response);
|
|
173
178
|
});
|
package/types/common.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ICustomer } from "./customer";
|
|
2
|
+
import {IProcessPaymentRequest} from "./checkout";
|
|
2
3
|
|
|
3
4
|
export interface IInlineCheckoutBaseOptions {
|
|
4
5
|
mode?: "production" | "sandbox" | "stage" | "development";
|
|
@@ -7,7 +8,7 @@ export interface IInlineCheckoutBaseOptions {
|
|
|
7
8
|
callBack?: (response: any) => void;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
export interface IConfigureCheckout {
|
|
11
|
+
export interface IConfigureCheckout extends IProcessPaymentRequest{
|
|
11
12
|
customer: ICustomer;
|
|
12
13
|
secureToken: string;
|
|
13
14
|
}
|