tonder-web-sdk 1.16.1 → 1.16.6-beta.DEV-1433.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 +134 -40
- package/package.json +29 -6
- package/types/card.d.ts +17 -17
- package/types/checkout.d.ts +85 -87
- package/types/common.d.ts +8 -2
- package/types/customer.d.ts +10 -10
- package/types/index.d.ts +9 -11
- package/types/inlineCheckout.d.ts +81 -61
- package/types/liteInlineCheckout.d.ts +78 -83
- package/types/paymentMethod.d.ts +17 -17
- package/types/transaction.d.ts +94 -94
- package/v1/bundle.min.js +1 -18
- package/.env-example +0 -1
- package/cypress/e2e/1-getting-started/todo.cy.js +0 -143
- package/cypress/e2e/2-advanced-examples/actions.cy.js +0 -299
- package/cypress/e2e/2-advanced-examples/aliasing.cy.js +0 -39
- package/cypress/e2e/2-advanced-examples/assertions.cy.js +0 -176
- package/cypress/e2e/2-advanced-examples/connectors.cy.js +0 -98
- package/cypress/e2e/2-advanced-examples/cookies.cy.js +0 -118
- package/cypress/e2e/2-advanced-examples/cypress_api.cy.js +0 -185
- package/cypress/e2e/2-advanced-examples/files.cy.js +0 -85
- package/cypress/e2e/2-advanced-examples/location.cy.js +0 -32
- package/cypress/e2e/2-advanced-examples/misc.cy.js +0 -104
- package/cypress/e2e/2-advanced-examples/navigation.cy.js +0 -56
- package/cypress/e2e/2-advanced-examples/network_requests.cy.js +0 -163
- package/cypress/e2e/2-advanced-examples/querying.cy.js +0 -114
- package/cypress/e2e/2-advanced-examples/spies_stubs_clocks.cy.js +0 -201
- package/cypress/e2e/2-advanced-examples/storage.cy.js +0 -110
- package/cypress/e2e/2-advanced-examples/traversal.cy.js +0 -121
- package/cypress/e2e/2-advanced-examples/utilities.cy.js +0 -108
- package/cypress/e2e/2-advanced-examples/viewport.cy.js +0 -58
- package/cypress/e2e/2-advanced-examples/waiting.cy.js +0 -30
- package/cypress/e2e/2-advanced-examples/window.cy.js +0 -22
- package/cypress/fixtures/example.json +0 -5
- package/cypress/support/commands.js +0 -25
- package/cypress/support/e2e.js +0 -20
- package/cypress.config.js +0 -9
- package/index.js.example +0 -50
- package/samples/react/README.md +0 -70
- package/samples/react/build/asset-manifest.json +0 -16
- package/samples/react/build/favicon.ico +0 -0
- package/samples/react/build/index.html +0 -1
- package/samples/react/build/logo192.png +0 -0
- package/samples/react/build/logo512.png +0 -0
- package/samples/react/build/manifest.json +0 -25
- package/samples/react/build/robots.txt +0 -3
- package/samples/react/build/static/css/main.073c9b0a.css +0 -2
- package/samples/react/build/static/css/main.073c9b0a.css.map +0 -1
- package/samples/react/build/static/js/787.b83ed06f.chunk.js +0 -2
- package/samples/react/build/static/js/787.b83ed06f.chunk.js.map +0 -1
- package/samples/react/build/static/js/main.0a848807.js +0 -3
- package/samples/react/build/static/js/main.0a848807.js.LICENSE.txt +0 -39
- package/samples/react/build/static/js/main.0a848807.js.map +0 -1
- package/samples/react/build/static/media/sdk-icons.b491623214b2af4cccdb.png +0 -0
- package/samples/react/package-lock.json +0 -28973
- package/samples/react/package.json +0 -44
- package/samples/react/public/favicon.ico +0 -0
- package/samples/react/public/index.html +0 -43
- package/samples/react/public/logo192.png +0 -0
- package/samples/react/public/logo512.png +0 -0
- package/samples/react/public/manifest.json +0 -25
- package/samples/react/public/robots.txt +0 -3
- package/samples/react/src/App.css +0 -38
- package/samples/react/src/App.js +0 -22
- package/samples/react/src/App.test.js +0 -8
- package/samples/react/src/assets/img/sdk-icons.png +0 -0
- package/samples/react/src/components/Cart.js +0 -29
- package/samples/react/src/components/ProductCard.js +0 -27
- package/samples/react/src/context/CartContext.js +0 -116
- package/samples/react/src/index.css +0 -13
- package/samples/react/src/index.js +0 -17
- package/samples/react/src/logo.svg +0 -1
- package/samples/react/src/reportWebVitals.js +0 -13
- package/samples/react/src/screens/Checkout.js +0 -82
- package/samples/react/src/screens/Store.js +0 -21
- package/samples/react/src/setupTests.js +0 -5
- package/samples/react/src/storeProducts.js +0 -30
- package/src/classes/3dsHandler.js +0 -203
- package/src/classes/BaseInlineCheckout.js +0 -324
- package/src/classes/LiteInlineCheckout.js +0 -220
- package/src/classes/checkout.js +0 -125
- package/src/classes/globalLoader.js +0 -29
- package/src/classes/inlineCheckout.js +0 -515
- package/src/data/apmApi.js +0 -44
- package/src/data/businessApi.js +0 -19
- package/src/data/cardApi.js +0 -143
- package/src/data/checkoutApi.js +0 -92
- package/src/data/customerApi.js +0 -37
- package/src/data/index.js +0 -17
- package/src/data/openPayApi.js +0 -16
- package/src/data/skyflowApi.js +0 -18
- package/src/helpers/skyflow.js +0 -361
- package/src/helpers/styles.js +0 -61
- package/src/helpers/template-skeleton.js +0 -59
- package/src/helpers/template.js +0 -743
- package/src/helpers/utils.js +0 -163
- package/src/helpers/validations.js +0 -54
- package/src/index-dev.js +0 -307
- package/src/index.html +0 -172
- package/src/index.js +0 -15
- package/src/shared/catalog/paymentMethodsCatalog.js +0 -247
- package/src/shared/constants/messages.js +0 -10
- package/src/shared/constants/paymentMethodAPM.js +0 -63
- package/src/shared/constants/tonderUrl.js +0 -8
- package/webpack.config.js +0 -77
package/src/data/cardApi.js
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildErrorResponse,
|
|
3
|
-
buildErrorResponseFromCatch,
|
|
4
|
-
} from "../helpers/utils";
|
|
5
|
-
import {MESSAGES} from "../shared/constants/messages";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Saves or updates a customer's card information.
|
|
9
|
-
*
|
|
10
|
-
* This function sends a POST request to save or update the card information for a customer.
|
|
11
|
-
*
|
|
12
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
13
|
-
* @param {string} customerToken - The customer's authentication token.
|
|
14
|
-
* @param {string} secureToken - Token generated by secure-token endpoint.
|
|
15
|
-
* @param {string | number} businessId - The business ID.
|
|
16
|
-
* @param {import("../../types").ISaveCardSkyflowRequest} data - The card information to be saved.
|
|
17
|
-
* @returns {Promise<import("../../types").ISaveCardResponse>} The saved card data.
|
|
18
|
-
*
|
|
19
|
-
* @throws {import("../../types").IApiError} Throws an error object if the save/update operation fails.
|
|
20
|
-
*/
|
|
21
|
-
export async function saveCustomerCard(
|
|
22
|
-
baseUrl,
|
|
23
|
-
customerToken,
|
|
24
|
-
secureToken,
|
|
25
|
-
businessId,
|
|
26
|
-
data,
|
|
27
|
-
) {
|
|
28
|
-
try {
|
|
29
|
-
const url = `${baseUrl}/api/v1/business/${businessId}/cards/`;
|
|
30
|
-
const response = await fetch(url, {
|
|
31
|
-
method: "POST",
|
|
32
|
-
headers: {
|
|
33
|
-
Authorization: `Bearer ${secureToken}`,
|
|
34
|
-
"User-Token": customerToken,
|
|
35
|
-
"Content-Type": "application/json",
|
|
36
|
-
},
|
|
37
|
-
body: JSON.stringify(data),
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (response.ok) return await response.json();
|
|
41
|
-
|
|
42
|
-
const res_json = await response.json();
|
|
43
|
-
if (response.status === 409) {
|
|
44
|
-
if ((res_json.error = "Card number already exists.")) {
|
|
45
|
-
return {
|
|
46
|
-
code: 200,
|
|
47
|
-
body: res_json,
|
|
48
|
-
name: "",
|
|
49
|
-
message: res_json.error,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
throw await buildErrorResponse(response, res_json);
|
|
54
|
-
} catch (error) {
|
|
55
|
-
throw buildErrorResponseFromCatch(error);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Removes a customer's card.
|
|
61
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
62
|
-
* @param {string} customerToken - The customer's authentication token.
|
|
63
|
-
* @param {string} secureToken - Token generated by secure-token endpoint.
|
|
64
|
-
* @param {string} skyflowId - The Skyflow ID of the card to be removed.
|
|
65
|
-
* @param {string} businessId - The business ID.
|
|
66
|
-
* @returns {Promise<string>} The result of the card removal operation.
|
|
67
|
-
*
|
|
68
|
-
* @throws {import("../../types").IApiError} Throws an error object if the operation fails.
|
|
69
|
-
*/
|
|
70
|
-
export async function removeCustomerCard(
|
|
71
|
-
baseUrl,
|
|
72
|
-
customerToken,
|
|
73
|
-
secureToken,
|
|
74
|
-
skyflowId = "",
|
|
75
|
-
businessId,
|
|
76
|
-
) {
|
|
77
|
-
try {
|
|
78
|
-
const url = `${baseUrl}/api/v1/business/${businessId}/cards/${skyflowId}`;
|
|
79
|
-
|
|
80
|
-
const response = await fetch(url, {
|
|
81
|
-
method: "DELETE",
|
|
82
|
-
headers: {
|
|
83
|
-
Authorization: `Bearer ${secureToken}`,
|
|
84
|
-
"Content-Type": "application/json",
|
|
85
|
-
"User-Token": customerToken,
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if(response.status === 204) return MESSAGES.cardSaved;
|
|
90
|
-
if (response.ok && "json" in response) return await response.json();
|
|
91
|
-
const res_json = await response.json();
|
|
92
|
-
|
|
93
|
-
throw await buildErrorResponse(response, res_json);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
throw buildErrorResponseFromCatch(error);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Fetches a customer's saved cards.
|
|
101
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
102
|
-
* @param {string} customerToken - The customer's authentication token.
|
|
103
|
-
* @param {string} secureToken - Token generated by secure-token endpoint.
|
|
104
|
-
* @param {string} businessId - The business ID.
|
|
105
|
-
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
106
|
-
* @returns {Promise<import("../../types").ICustomerCardsResponse>} The customer's saved cards.
|
|
107
|
-
*
|
|
108
|
-
* @throws {import("../../types").IApiError} Throws an error object if the operation fails.
|
|
109
|
-
*/
|
|
110
|
-
export async function fetchCustomerCards(
|
|
111
|
-
baseUrl,
|
|
112
|
-
customerToken,
|
|
113
|
-
secureToken,
|
|
114
|
-
businessId,
|
|
115
|
-
signal= null,
|
|
116
|
-
) {
|
|
117
|
-
try {
|
|
118
|
-
const url = `${baseUrl}/api/v1/business/${businessId}/cards/`;
|
|
119
|
-
const response = await fetch(url, {
|
|
120
|
-
method: "GET",
|
|
121
|
-
headers: {
|
|
122
|
-
Authorization: `Bearer ${secureToken}`,
|
|
123
|
-
"User-Token": customerToken,
|
|
124
|
-
},
|
|
125
|
-
signal,
|
|
126
|
-
});
|
|
127
|
-
if (response.ok) return await response.json();
|
|
128
|
-
if (response.status === 401) {
|
|
129
|
-
return {
|
|
130
|
-
code: 401,
|
|
131
|
-
body: {},
|
|
132
|
-
name: "",
|
|
133
|
-
message: "Unauthorized",
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const res_json = await response.json();
|
|
138
|
-
|
|
139
|
-
throw await buildErrorResponse(response, res_json, MESSAGES.getCardsError);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
throw buildErrorResponseFromCatch(error, MESSAGES.getCardsError);
|
|
142
|
-
}
|
|
143
|
-
}
|
package/src/data/checkoutApi.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a new order in the system.
|
|
3
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
4
|
-
* @param {string} apiKey - The API key for authentication.
|
|
5
|
-
* @param {Object} orderItems - The items to be included in the order.
|
|
6
|
-
* @returns {Promise<Object>} The created order data.
|
|
7
|
-
*/
|
|
8
|
-
export async function createOrder(baseUrl, apiKey, orderItems) {
|
|
9
|
-
const url = `${baseUrl}/api/v1/orders/`;
|
|
10
|
-
const data = orderItems;
|
|
11
|
-
const response = await fetch(url, {
|
|
12
|
-
method: "POST",
|
|
13
|
-
headers: {
|
|
14
|
-
"Content-Type": "application/json",
|
|
15
|
-
Authorization: `Token ${apiKey}`,
|
|
16
|
-
},
|
|
17
|
-
body: JSON.stringify(data),
|
|
18
|
-
});
|
|
19
|
-
if (response.status === 201) {
|
|
20
|
-
const jsonResponse = await response.json();
|
|
21
|
-
return jsonResponse;
|
|
22
|
-
} else {
|
|
23
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Creates a new payment in the system.
|
|
29
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
30
|
-
* @param {string} apiKey - The API key for authentication.
|
|
31
|
-
* @param {Object} paymentItems - The payment details.
|
|
32
|
-
* @returns {Promise<Object>} The created payment data.
|
|
33
|
-
*/
|
|
34
|
-
export async function createPayment(baseUrl, apiKey, paymentItems) {
|
|
35
|
-
const url = `${baseUrl}/api/v1/business/${paymentItems.business_pk}/payments/`;
|
|
36
|
-
const data = paymentItems;
|
|
37
|
-
const response = await fetch(url, {
|
|
38
|
-
method: "POST",
|
|
39
|
-
headers: {
|
|
40
|
-
"Content-Type": "application/json",
|
|
41
|
-
Authorization: `Token ${apiKey}`,
|
|
42
|
-
},
|
|
43
|
-
body: JSON.stringify(data),
|
|
44
|
-
});
|
|
45
|
-
if (response.status >= 200 && response.status <=299) {
|
|
46
|
-
const jsonResponse = await response.json();
|
|
47
|
-
return jsonResponse;
|
|
48
|
-
} else {
|
|
49
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Initiates the checkout process.
|
|
55
|
-
*
|
|
56
|
-
* This function sends a POST request to the checkout router API with the provided
|
|
57
|
-
* checkout details. If the request is successful, it returns the response data.
|
|
58
|
-
* If the request fails, it throws an error that includes the status and details of the failure.
|
|
59
|
-
*
|
|
60
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
61
|
-
* @param {string} apiKey - The API key for authentication.
|
|
62
|
-
* @param {import("../../types").IStartCheckoutRequest | import("../../types").IStartCheckoutIdRequest} routerItems - The checkout details to be sent in the request body.
|
|
63
|
-
* @returns {Promise<import("../../types").IStartCheckoutResponse>} The checkout process result.
|
|
64
|
-
*
|
|
65
|
-
* @throws {Error} Throws an error if the checkout process fails. The error object contains
|
|
66
|
-
* additional `details` property with the response from the server if available.
|
|
67
|
-
* @property {import("../../types").IStartCheckoutErrorResponse} error.details - The response body from the server when an error occurs.
|
|
68
|
-
*/
|
|
69
|
-
export async function startCheckoutRouter(baseUrl, apiKey, routerItems) {
|
|
70
|
-
try {
|
|
71
|
-
const url = `${baseUrl}/api/v1/checkout-router/`;
|
|
72
|
-
const data = routerItems;
|
|
73
|
-
const response = await fetch(url, {
|
|
74
|
-
method: "POST",
|
|
75
|
-
headers: {
|
|
76
|
-
"Content-Type": "application/json",
|
|
77
|
-
Authorization: `Token ${apiKey}`,
|
|
78
|
-
},
|
|
79
|
-
body: JSON.stringify(data),
|
|
80
|
-
});
|
|
81
|
-
if (response.status >= 200 && response.status <= 299) {
|
|
82
|
-
return await response.json();
|
|
83
|
-
} else {
|
|
84
|
-
const errorResponse = await response.json();
|
|
85
|
-
const error = new Error("Failed to start checkout router");
|
|
86
|
-
error.details = errorResponse;
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
} catch (error) {
|
|
90
|
-
throw error
|
|
91
|
-
}
|
|
92
|
-
}
|
package/src/data/customerApi.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registers a new customer or fetches an existing customer.
|
|
3
|
-
* @param {string} baseUrl - The base URL of the API.
|
|
4
|
-
* @param {string} apiKey - The API key for authentication.
|
|
5
|
-
* @param {Object} customer - The customer data.
|
|
6
|
-
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
7
|
-
* @returns {Promise<Object>} The registered or fetched customer data.
|
|
8
|
-
*/
|
|
9
|
-
export async function registerOrFetchCustomer(
|
|
10
|
-
baseUrl,
|
|
11
|
-
apiKey,
|
|
12
|
-
customer,
|
|
13
|
-
signal = null,
|
|
14
|
-
) {
|
|
15
|
-
const url = `${baseUrl}/api/v1/customer/`;
|
|
16
|
-
const data = {
|
|
17
|
-
email: customer.email,
|
|
18
|
-
first_name: customer?.firstName,
|
|
19
|
-
last_name: customer?.lastName,
|
|
20
|
-
phone: customer?.phone,
|
|
21
|
-
};
|
|
22
|
-
const response = await fetch(url, {
|
|
23
|
-
method: "POST",
|
|
24
|
-
headers: {
|
|
25
|
-
"Content-Type": "application/json",
|
|
26
|
-
Authorization: `Token ${apiKey}`,
|
|
27
|
-
},
|
|
28
|
-
signal: signal,
|
|
29
|
-
body: JSON.stringify(data),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
if (response.status === 201) {
|
|
33
|
-
return await response.json();
|
|
34
|
-
} else {
|
|
35
|
-
throw new Error(`Error: ${response.statusText}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
package/src/data/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { fetchBusiness } from './businessApi';
|
|
2
|
-
import { registerOrFetchCustomer } from './customerApi';
|
|
3
|
-
import { createOrder } from './checkoutApi';
|
|
4
|
-
import { saveCustomerCard, removeCustomerCard, fetchCustomerCards } from './cardApi';
|
|
5
|
-
import { fetchCustomerAPMs } from './apmApi';
|
|
6
|
-
import { getOpenpayDeviceSessionID } from './openPayApi';
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
registerOrFetchCustomer,
|
|
10
|
-
createOrder,
|
|
11
|
-
saveCustomerCard,
|
|
12
|
-
removeCustomerCard,
|
|
13
|
-
fetchCustomerCards,
|
|
14
|
-
fetchBusiness,
|
|
15
|
-
fetchCustomerAPMs,
|
|
16
|
-
getOpenpayDeviceSessionID
|
|
17
|
-
};
|
package/src/data/openPayApi.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates an Openpay device session ID.
|
|
3
|
-
* @param {string} merchant_id - The Openpay merchant ID.
|
|
4
|
-
* @param {string} public_key - The Openpay public key.
|
|
5
|
-
* @param {AbortSignal} signal - The abort signal to cancel the request.
|
|
6
|
-
* @returns {Promise<string>} The generated device session ID.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export async function getOpenpayDeviceSessionID(merchant_id, public_key, signal) {
|
|
10
|
-
let openpay = await window.OpenPay;
|
|
11
|
-
openpay.setId(merchant_id);
|
|
12
|
-
openpay.setApiKey(public_key);
|
|
13
|
-
openpay.setSandboxMode(true);
|
|
14
|
-
var response = await openpay.deviceData.setup({signal});
|
|
15
|
-
return response;
|
|
16
|
-
}
|
package/src/data/skyflowApi.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export async function getVaultToken (baseUrl, apiKey, signal = null){
|
|
4
|
-
const response = await fetch(`${baseUrl}/api/v1/vault-token/`, {
|
|
5
|
-
method: 'GET',
|
|
6
|
-
headers: {
|
|
7
|
-
'Authorization': `Token ${apiKey}`,
|
|
8
|
-
},
|
|
9
|
-
signal: signal,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
if (response.ok) {
|
|
13
|
-
const responseBody = await response.json();
|
|
14
|
-
return responseBody.token;
|
|
15
|
-
} else {
|
|
16
|
-
throw new Error('Failed to retrieve bearer token');
|
|
17
|
-
}
|
|
18
|
-
}
|
package/src/helpers/skyflow.js
DELETED
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
import { defaultStyles } from "./styles";
|
|
2
|
-
import {getVaultToken} from "../data/skyflowApi";
|
|
3
|
-
import {buildErrorResponseFromCatch} from "./utils";
|
|
4
|
-
|
|
5
|
-
export async function initSkyflow(
|
|
6
|
-
vaultId,
|
|
7
|
-
vaultUrl,
|
|
8
|
-
baseUrl,
|
|
9
|
-
apiKey,
|
|
10
|
-
signal,
|
|
11
|
-
customStyles = {},
|
|
12
|
-
collectorIds,
|
|
13
|
-
) {
|
|
14
|
-
const skyflow = await initializeSkyflow(vaultId, vaultUrl, baseUrl, apiKey, signal);
|
|
15
|
-
|
|
16
|
-
// Create collect Container.
|
|
17
|
-
const collectContainer = await skyflow.container(
|
|
18
|
-
Skyflow.ContainerType.COLLECT
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
// Custom styles for collect elements.
|
|
22
|
-
var collectStylesOptions = Object.keys(customStyles).length === 0 ? defaultStyles : customStyles
|
|
23
|
-
|
|
24
|
-
const stylesForCardNumber = { ...collectStylesOptions.inputStyles.base };
|
|
25
|
-
stylesForCardNumber.textIndent = '44px';
|
|
26
|
-
|
|
27
|
-
const lengthMatchRule = {
|
|
28
|
-
type: Skyflow.ValidationRuleType.LENGTH_MATCH_RULE,
|
|
29
|
-
params: {
|
|
30
|
-
max: 70,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const cardHolderNameElement = await collectContainer.create({
|
|
37
|
-
table: "cards",
|
|
38
|
-
column: "cardholder_name",
|
|
39
|
-
...collectStylesOptions,
|
|
40
|
-
label: collectStylesOptions.labels?.nameLabel,
|
|
41
|
-
placeholder: collectStylesOptions.placeholders?.namePlaceholder,
|
|
42
|
-
type: Skyflow.ElementType.CARDHOLDER_NAME,
|
|
43
|
-
validations: [lengthMatchRule, regexMatchRule],
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
handleSkyflowElementEvents(
|
|
47
|
-
cardHolderNameElement,
|
|
48
|
-
"titular de la tarjeta",
|
|
49
|
-
collectStylesOptions.errorTextStyles
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
// Create collect elements.
|
|
53
|
-
const cardNumberElement = await collectContainer.create({
|
|
54
|
-
table: "cards",
|
|
55
|
-
column: "card_number",
|
|
56
|
-
...collectStylesOptions,
|
|
57
|
-
inputStyles: {
|
|
58
|
-
...collectStylesOptions.inputStyles,
|
|
59
|
-
base: stylesForCardNumber
|
|
60
|
-
},
|
|
61
|
-
label: collectStylesOptions.labels?.cardLabel,
|
|
62
|
-
placeholder: collectStylesOptions.placeholders?.cardPlaceholder,
|
|
63
|
-
type: Skyflow.ElementType.CARD_NUMBER,
|
|
64
|
-
validations: [regexMatchRule],
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
handleSkyflowElementEvents(
|
|
68
|
-
cardNumberElement,
|
|
69
|
-
"número de tarjeta",
|
|
70
|
-
collectStylesOptions.errorTextStyles
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const cvvElement = await collectContainer.create({
|
|
74
|
-
table: "cards",
|
|
75
|
-
column: "cvv",
|
|
76
|
-
...collectStylesOptions,
|
|
77
|
-
label: collectStylesOptions.labels?.cvvLabel,
|
|
78
|
-
placeholder: collectStylesOptions.placeholders?.cvvPlaceholder,
|
|
79
|
-
type: Skyflow.ElementType.CVV,
|
|
80
|
-
validations: [regexMatchRule],
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
handleSkyflowElementEvents(
|
|
84
|
-
cvvElement,
|
|
85
|
-
"",
|
|
86
|
-
collectStylesOptions.errorTextStyles
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
const expiryMonthElement = await collectContainer.create({
|
|
90
|
-
table: "cards",
|
|
91
|
-
column: "expiration_month",
|
|
92
|
-
...collectStylesOptions,
|
|
93
|
-
label: collectStylesOptions.labels?.expiryDateLabel,
|
|
94
|
-
placeholder: collectStylesOptions.placeholders?.expiryMonthPlaceholder,
|
|
95
|
-
type: Skyflow.ElementType.EXPIRATION_MONTH,
|
|
96
|
-
validations: [regexMatchRule],
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
handleSkyflowElementEvents(
|
|
100
|
-
expiryMonthElement,
|
|
101
|
-
"",
|
|
102
|
-
collectStylesOptions.errorTextStyles
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const expiryYearElement = await collectContainer.create({
|
|
106
|
-
table: "cards",
|
|
107
|
-
column: "expiration_year",
|
|
108
|
-
...collectStylesOptions,
|
|
109
|
-
label: "",
|
|
110
|
-
placeholder: collectStylesOptions.placeholders?.expiryYearPlaceholder,
|
|
111
|
-
type: Skyflow.ElementType.EXPIRATION_YEAR,
|
|
112
|
-
validations: [regexMatchRule],
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
handleSkyflowElementEvents(
|
|
116
|
-
expiryYearElement,
|
|
117
|
-
"",
|
|
118
|
-
collectStylesOptions.errorTextStyles
|
|
119
|
-
);
|
|
120
|
-
|
|
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
|
-
|
|
147
|
-
return {
|
|
148
|
-
container: collectContainer,
|
|
149
|
-
elements: {
|
|
150
|
-
cardHolderNameElement,
|
|
151
|
-
cardNumberElement,
|
|
152
|
-
cvvElement,
|
|
153
|
-
expiryMonthElement,
|
|
154
|
-
expiryYearElement
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
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
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
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
|
-
|
|
246
|
-
function handleSkyflowElementEvents(element, fieldMessage= "", error_styles = {}, resetOnFocus = true, requiredMessage = "El campo es requerido", invalidMessage= "El campo es inválido") {
|
|
247
|
-
if ("on" in element) {
|
|
248
|
-
element.on(Skyflow.EventName.CHANGE, (state) => {
|
|
249
|
-
updateErrorLabel(element, error_styles, "transparent")
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
element.on(Skyflow.EventName.BLUR, (state) => {
|
|
253
|
-
if (!state.isValid) {
|
|
254
|
-
const msj_error = state.isEmpty ? requiredMessage : fieldMessage != "" ?`El campo ${fieldMessage} es inválido`: invalidMessage;
|
|
255
|
-
element.setError(msj_error);
|
|
256
|
-
}
|
|
257
|
-
updateErrorLabel(element, error_styles)
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
element.on(Skyflow.EventName.FOCUS, (state) => {
|
|
261
|
-
updateErrorLabel(element, error_styles, "transparent")
|
|
262
|
-
element.resetError();
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function updateErrorLabel(element, errorStyles, color = "" ){
|
|
268
|
-
if(Object.keys(errorStyles).length > 0){
|
|
269
|
-
element.update({
|
|
270
|
-
errorTextStyles: {
|
|
271
|
-
...errorStyles,
|
|
272
|
-
base: {
|
|
273
|
-
...(errorStyles.base && {...errorStyles.base}),
|
|
274
|
-
...(color != "" && {color})
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
export async function getSkyflowTokens({baseUrl, apiKey, vault_id, vault_url, data }) {
|
|
282
|
-
const skyflow = Skyflow.init({
|
|
283
|
-
vaultID: vault_id,
|
|
284
|
-
vaultURL: vault_url,
|
|
285
|
-
getBearerToken: async () => await getVaultToken(baseUrl, apiKey),
|
|
286
|
-
options: {
|
|
287
|
-
logLevel: Skyflow.LogLevel.ERROR,
|
|
288
|
-
env: Skyflow.Env.DEV,
|
|
289
|
-
},
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
const collectContainer = skyflow.container(Skyflow.ContainerType.COLLECT);
|
|
293
|
-
|
|
294
|
-
const fieldPromises = await getFieldsPromise(data, collectContainer);
|
|
295
|
-
|
|
296
|
-
const result = await Promise.all(fieldPromises);
|
|
297
|
-
const mountFail = result.some((item) => !item);
|
|
298
|
-
|
|
299
|
-
if (mountFail) {
|
|
300
|
-
throw buildErrorResponseFromCatch(
|
|
301
|
-
Error("Ocurrió un error al montar los campos de la tarjeta"),
|
|
302
|
-
);
|
|
303
|
-
} else {
|
|
304
|
-
try {
|
|
305
|
-
const collectResponseSkyflowTonder = await collectContainer.collect();
|
|
306
|
-
if (collectResponseSkyflowTonder)
|
|
307
|
-
return collectResponseSkyflowTonder["records"][0]["fields"];
|
|
308
|
-
throw buildErrorResponseFromCatch(
|
|
309
|
-
Error("Por favor, verifica todos los campos de tu tarjeta"),
|
|
310
|
-
);
|
|
311
|
-
} catch (error) {
|
|
312
|
-
throw buildErrorResponseFromCatch(error);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
async function getFieldsPromise(data, collectContainer) {
|
|
317
|
-
const fields = await getFields(data, collectContainer);
|
|
318
|
-
if (!fields) return [];
|
|
319
|
-
return fields.map((field) => {
|
|
320
|
-
return new Promise((resolve) => {
|
|
321
|
-
const div = document.createElement("div");
|
|
322
|
-
div.hidden = true;
|
|
323
|
-
div.id = `id-${field.key}`;
|
|
324
|
-
document.querySelector(`body`)?.appendChild(div);
|
|
325
|
-
setTimeout(() => {
|
|
326
|
-
field.element.mount(`#id-${field.key}`);
|
|
327
|
-
setInterval(() => {
|
|
328
|
-
if (field.element.isMounted()) {
|
|
329
|
-
const value = data[field.key];
|
|
330
|
-
field.element.update({ value: value });
|
|
331
|
-
return resolve(field.element.isMounted());
|
|
332
|
-
}
|
|
333
|
-
}, 120);
|
|
334
|
-
}, 120);
|
|
335
|
-
});
|
|
336
|
-
})
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async function getFields(data, collectContainer) {
|
|
340
|
-
return await Promise.all(
|
|
341
|
-
Object.keys(data).map(async (key) => {
|
|
342
|
-
const cardHolderNameElement = await collectContainer.create({
|
|
343
|
-
table: "cards",
|
|
344
|
-
column: key,
|
|
345
|
-
type: Skyflow.ElementType.INPUT_FIELD,
|
|
346
|
-
});
|
|
347
|
-
return { element: cardHolderNameElement, key: key };
|
|
348
|
-
})
|
|
349
|
-
)
|
|
350
|
-
}
|
|
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
|
-
|