diff --git a/components/sidebar.php b/components/sidebar.php index ccb2e58..6fc78b2 100644 --- a/components/sidebar.php +++ b/components/sidebar.php @@ -8,7 +8,7 @@ class="flex items-center pl-2.5 mb-5" > Culqi Logo diff --git a/index.php b/index.php index 7d4c8e2..ade1210 100644 --- a/index.php +++ b/index.php @@ -41,7 +41,6 @@ class="bg-blue-500 hover:bg-blue-700 px-5 py-4 leading-5 rounded-full font-semib diff --git a/js/config/culqi3ds.js b/js/config/culqi3ds.js index 815c6f1..bc99f72 100644 --- a/js/config/culqi3ds.js +++ b/js/config/culqi3ds.js @@ -5,10 +5,7 @@ Culqi3DS.options = { showLoading: true, showIcon: true, closeModalAction: () => window.location.reload(true) - // style: { - // btnColor: "red", - // btnTextColor: "yellow", - // }, + }; Culqi3DS.publicKey = checkoutConfig.PUBLIC_KEY; diff --git a/js/config/index.js b/js/config/index.js index 2cf4bef..4347372 100644 --- a/js/config/index.js +++ b/js/config/index.js @@ -10,54 +10,11 @@ export const checkoutConfig = Object.freeze({ URL_BASE: "http://localhost/culqi-demos-Php-checkout-charge" }); -//genera datos nuevos en el load -function generateRandomEmail() { - const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; - const domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'culqi.com']; - let username = ''; - - // Generar nombre del correo (username) de long entre 6 y 12 caracteres - const usernameLength = Math.floor(Math.random() * 7) + 6; - - for (let i = 0; i < usernameLength; i++) { - const randomChar = chars.charAt(Math.floor(Math.random() * chars.length)); - username += randomChar; - } - - // Elegir un dominio aleatorio - const domain = domains[Math.floor(Math.random() * domains.length)]; - - // Devolver el correo electrónico completo - return `${username}@${domain}`; -} -//genera nombre y apellido - const generateRandomName = (length) => { - const chars = 'abcdefghijklmnopqrstuvwxyz'; - let name = ''; - - // Generar una cadena de letras aleatorias de longitud dada - for (let i = 0; i < length; i++) { - const randomChar = chars.charAt(Math.floor(Math.random() * chars.length)); - name += randomChar; - } - - // Capitalizar la primera letra - return name.charAt(0).toUpperCase() + name.slice(1); -}; - -// Generar un nombre de 6-10 letras aleatorias -const firstName = generateRandomName(Math.floor(Math.random() * 5) + 6); // Longitud entre 6 y 10 -const lastName = generateRandomName(Math.floor(Math.random() * 5) + 6); -const phone = "9" + Array.from({ length: 8 }, () => Math.floor(Math.random() * 10)).join(''); -const email = generateRandomEmail(); -const countryCode = Math.random() < 0.5 ? "PE":"US"; - - export const customerInfo = { - firstName: firstName, - lastName: lastName, +export const chargeInfo = { + firstName: "Dennis", + lastName: "Demo", address: "Av siempre viva", addressCity: "Lima", - countryCode , - phone: phone, - email: generateRandomEmail() //"review" + Math.floor(Math.random() * 100) + "@culqi.com" + phone: "999999999", + email: "review1" + Math.floor(Math.random() * 100) + "@culqi.com" }; diff --git a/js/main.js b/js/main.js index 9425a4a..a8f15aa 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,5 @@ -import { checkoutConfig, customerInfo } from "./config/index.js"; +import { checkoutConfig } from "./config/index.js"; +import { generateCustomerData, isValidEmail, isValidPhoneNumber } from './utils/helpers.js'; import { culqiConfig } from "./config/checkout.js"; import "./config/culqi3ds.js"; import { @@ -76,15 +77,15 @@ const handledContentLoad = async () => { }); } - objResponse = response.data.object; + objResponse = response.data; statusCode = response.statusCode; console.log("Status code: ", statusCode); if (statusCode === 201) { - if (objResponse === "charge" || objResponse === "card") { + if (objResponse.object === "charge" || objResponse.object === "card") { selectors.cardResponseList.forEach((el) => { - el.innerHTML = "OPERACIÓN REALIZADA EXITOSAMENTE"; + el.innerHTML = "OPERACIÓN REALIZADA EXITOSAMENTE
ID: "+ objResponse.id; }); } } @@ -194,38 +195,69 @@ const handledContentLoad = async () => { Culqi3DS.initAuthentication(tokenId); }; - const createCustomer = async () => { + const createCustomer = async () => { selectors.customerResponse.innerHTML = spinerHtml; + + const customerInfo = { + firstName: selectors.customersFirstNameElement.value, + lastName: selectors.customersLastNameElement.value, + address: selectors.customersAddressElement.value, + addressCity: selectors.customersAddressCityElement.value, + countryCode: selectors.customersCountryCodeElement.value , + phone: selectors.customersPhoneElement.value.replace(/\s/g, ""), + email: selectors.customersEmailElement.value + }; + // Validar si algún campo requerido está vacío + const emptyFields = Object.entries(customerInfo).filter(([key, value]) => !value); + + if (emptyFields.length > 0) { + selectors.customerResponse.innerHTML = `Error: El campo ${emptyFields[0][0]} está vacío.`; + return; // Detener la ejecución si algún campo está vacío + } + + // Validar el correo electrónico + if (!isValidEmail(customerInfo.email)) { + selectors.customerResponse.innerHTML = "Error: Correo electrónico inválido."; + return; // Detener la ejecución si el correo electrónico no es válido + } + // Validación del número de teléfono + if (!isValidPhoneNumber(customerInfo.phone)) { + selectors.customerResponse.innerHTML = "Error: Número de teléfono inválido. Debe contener solo 9 dígitos."; + return; + } + + //validar solo US o PE + if (!['US', 'PE'].includes(customerInfo.countryCode)) { + selectors.customerResponse.innerHTML = "Error: Código de país inválido. Solo se acepta 'US' o 'PE'."; + return; // Detener la ejecución si el código de país no es válido + } const dataCustomer = await createCustomerImpl({ - ...customerInfo + ...customerInfo //captura del front la data de los input armar object customerInfo }); - - selectors.customerCustomFormElement.value = dataCustomer.data.id; - - selectors.customerResponse.innerHTML = dataCustomer.data.id; + + if ( dataCustomer.data.object === "error") { + if (dataCustomer.data.merchant_message.includes("Invalid value. It must be")) { + selectors.customerResponse.innerHTML = "Error de código de país";//mensaje countryCode + }else{ + selectors.customerResponse.innerHTML = dataCustomer.data.merchant_message;//error general + } + } else { + selectors.customerCustomFormElement.value = dataCustomer.data.id; + selectors.customerResponse.innerHTML = dataCustomer.data.id;//id + } + }; const loadCustomerExampleData = () => { + const customerInfo = generateCustomerData(); Object.keys(customerInfo).forEach((key) => { const selectorOption = selectors[ `customers${key.charAt(0).toUpperCase() + key.slice(1)}Element` - ]; + ]; if (selectorOption) { - selectorOption.value = customerInfo[key]; - } - }); - }; - // Función para actualizar los datos del cliente - const updateCustomerInfo = () => { - Object.keys(customerInfo).forEach((key) => { - const selectorOption = - selectors[ - `customers${key.charAt(0).toUpperCase() + key.slice(1)}Element` - ]; - if (selectorOption) { - customerInfo[key] = selectorOption.value; + selectorOption.value = customerInfo[key]; } }); }; @@ -248,7 +280,6 @@ const handledContentLoad = async () => { if (btnCreateCustomer) { btnCreateCustomer.addEventListener("click", () => { - updateCustomerInfo(); createCustomer(); }); } diff --git a/js/services/impl/index.js b/js/services/impl/index.js index cdda24f..64e016a 100644 --- a/js/services/impl/index.js +++ b/js/services/impl/index.js @@ -1,5 +1,5 @@ import Service from "../index.js"; -import { checkoutConfig, customerInfo } from "../../config/index.js"; +import { checkoutConfig, chargeInfo } from "../../config/index.js"; const service = new Service(); @@ -8,7 +8,6 @@ export const generateOrderImpl = async () => { currentDate.setDate(currentDate.getDate() + 1); var epochMilliseconds = currentDate.getTime(); var epochSeconds = Math.floor(epochMilliseconds / 1000); - console.log(epochSeconds); const bodyRequest = { amount: checkoutConfig.TOTAL_AMOUNT, @@ -16,10 +15,10 @@ export const generateOrderImpl = async () => { description: "Venta de prueba", order_number: "pedido-" + new Date().getTime(), client_details: { - first_name: customerInfo.firstName, - last_name: customerInfo.lastName, - email: customerInfo.email, - phone_number: customerInfo.phone + first_name: chargeInfo.firstName, + last_name: chargeInfo.lastName, + email: chargeInfo.email, + phone_number: chargeInfo.phone }, expiration_date: epochSeconds }; @@ -37,9 +36,9 @@ export const generateChargeImpl = async ({ currency_code: checkoutConfig.CURRENCY, email: email, token: tokenId, - first_name: customerInfo.firstName, - last_name: customerInfo.lastName, - phone_number: customerInfo.phone, + first_name: chargeInfo.firstName, + last_name: chargeInfo.lastName, + phone_number: chargeInfo.phone, device_finger_print_id: deviceId }; return service.generateCharge( diff --git a/js/services/index.js b/js/services/index.js index 3d0bdd7..98705fb 100644 --- a/js/services/index.js +++ b/js/services/index.js @@ -14,9 +14,15 @@ class Service { }, data }); - return { statusCode: response.status, data: response.data }; + + let dataParse = response.data + if (typeof response.data === "string") { + dataParse = JSON.parse(response.data); + } + return { statusCode: response.status, data: dataParse }; } catch (err) { - return { statusCode: err.response.status, data: err.response.data }; + let dataError = JSON.parse(err.response.data); + return { statusCode: err.response.status, data: dataError }; } }; diff --git a/js/utils/helpers.js b/js/utils/helpers.js index d74ee42..010b767 100644 --- a/js/utils/helpers.js +++ b/js/utils/helpers.js @@ -2,4 +2,65 @@ export const formatAmount = (amount) => { const amountStringified = amount.toString(); const decimalAmount = amountStringified.length - 2; return `${amountStringified.slice(0, decimalAmount)}.${amountStringified.slice(decimalAmount)}` -} \ No newline at end of file +} +export const isValidEmail = (email) => { + const re = /^[a-zA-Z0-9._]+@[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?$/; + return re.test(email); +}; + +export const isValidPhoneNumber = (phoneNumber) => { + const re = /^9\d{8}$/; // Solo acepta números que comiencen con '9' y tengan 9 dígitos. + return re.test(phoneNumber); +}; + +export function generateRandomEmail() { + const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; + const domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'culqi.com']; + let username = ''; + + // Generar nombre del correo (username) de long entre 6 y 12 caracteres + const usernameLength = Math.floor(Math.random() * 7) + 6; + + for (let i = 0; i < usernameLength; i++) { + const randomChar = chars.charAt(Math.floor(Math.random() * chars.length)); + username += randomChar; + } + + // Elegir un dominio aleatorio + const domain = domains[Math.floor(Math.random() * domains.length)]; + + // Devolver el correo electrónico completo + return `${username}@${domain}`; + } + //genera nombre y apellido +export function generateRandomName(length) { + const chars = 'abcdefghijklmnopqrstuvwxyz'; + let name = ''; + + // Generar una cadena de letras aleatorias de longitud dada + for (let i = 0; i < length; i++) { + const randomChar = chars.charAt(Math.floor(Math.random() * chars.length)); + name += randomChar; + } + + // Capitalizar la primera letra + return name.charAt(0).toUpperCase() + name.slice(1); + }; + + export const generateCustomerData = () => { + const firstName = generateRandomName(Math.floor(Math.random() * 5) + 6); + const lastName = generateRandomName(Math.floor(Math.random() * 5) + 6); + const phone = "9" + Array.from({ length: 8 }, () => Math.floor(Math.random() * 10)).join(''); + const email = generateRandomEmail(); + const countryCode = Math.random() < 0.5 ? "PE" : "US"; + + return { + firstName, + lastName, + address: "Av siempre viva", + addressCity: "Lima", + countryCode, + phone, + email + }; + }; \ No newline at end of file diff --git a/js/utils/selectors.js b/js/utils/selectors.js index a1a42f2..b5936ec 100644 --- a/js/utils/selectors.js +++ b/js/utils/selectors.js @@ -18,6 +18,7 @@ export const customersLastNameElement = document.getElementById("lastName"); export const customersAddressElement = document.getElementById("address"); export const customersAddressCityElement = document.getElementById("addressCity"); +export const customersCountryCodeElement = document.getElementById("countryCode"); export const customersEmailElement = document.getElementById("email"); export const customersPhoneElement = document.getElementById("phone"); /* END customer */