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.
@@ -11,18 +11,7 @@ export async function initSkyflow(
11
11
  customStyles = {},
12
12
  collectorIds,
13
13
  ) {
14
- const skyflow = await Skyflow.init({
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
- const regexMatchRule = {
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
- await mountElements(
140
- cardNumberElement,
141
- cvvElement,
142
- expiryMonthElement,
143
- expiryYearElement,
144
- cardHolderNameElement,
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
- async function mountElements(
160
- cardNumberElement,
161
- cvvElement,
162
- expiryMonthElement,
163
- expiryYearElement,
164
- cardHolderNameElement,
165
- ) {
166
- cardNumberElement.mount("#collectCardNumber");
167
- cvvElement.mount("#collectCvv");
168
- expiryMonthElement.mount("#collectExpirationMonth");
169
- expiryYearElement.mount("#collectExpirationYear");
170
- cardHolderNameElement.mount("#collectCardholderName");
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
+
@@ -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="card-item" id="card_container-${card.skyflow_id}">
343
- <input id="${card.skyflow_id}" class="card_selected" name="card_selected" type="radio"/>
344
- <label class="card-item-label" for="${card.skyflow_id}">
345
- <img class="card-image" src="${getCardType(card.card_scheme)}" />
346
- <div class="card-number">${card.card_number}</div>
347
- <div class="card-expiration">Exp. ${card.expiration_month}/${card.expiration_year}</div>
348
- <div class="card-delete-icon">
349
- <button id="delete_button_${card.skyflow_id}" class="card-delete-button">
350
- <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px">
351
- <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"/>
352
- </svg>
353
- </button>
354
- </div>
355
- </label>
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
- ${cardItemsHTML}
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
- customer: checkoutData.customer,
139
- secureToken: "eyJhbGc..."
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
  }