Personalización de Estilos de Vault mediante CSSCustomFile
Introducción
Esta documentación te proporcionará información detallada sobre cómo configurar tu archivo CSSCustomFile, que es un archivo JSON que te permitará editar la apariencia de tu Vault de Tarjetas DEUNA. Está dirigida a desarrolladores y comercios interesados en adaptar la apariencia de su bóveda a sus necesidades específicas.
Requisitos Previos
Antes de comenzar, asegúrese de contar con las siguientes informaciones:
- API keys 🔑
- Merchant ID 🪪
- Archivo JSON con estilos que desees configurar 💅
Configuración de Estilos Básicos
Puedes cambiar colores de fondo, textos, ajustar tamaños de fuente y definir márgenes y espaciados. Todo esto de acuerdo a solo un archivo JSON.
Estructura del archivo JSON CSSCustomFile
Recuerda que la propiedad
content
se utiliza para editar el contenido del texto, mientras que la propiedadstyle
se utiliza para modificar los estilos.
El archivo CSSCustomFile contiene la configuración de estilos del Vault. A continuación, se presenta una descripción detallada de los componentes editables y personalizables, así como un ejemplo de su estructura.
Ejemplo de una estructura JSON válida para la configuración de estilos:
{
"logoUrl": "https://assets-global.website-files.com/62e806ed6cc7b20ca6dc2b93/64c2aee779502b3676e1024a_Logo%20DEUNA.png",
"theme": {
"mainColor": "#FFC0CB",
"secondaryColor": "#7FFFD4"
},
"title": "Pago con tarjeta crédito o débito",
"header": {
"content": "Ingresa los datos de tu tarjeta",
"style": {
"color": "#333333"
}
},
"header2": {
"content": "Detalles de Pago",
"style": {
"color": "#393E41"
}
},
"nameInput": {
"content": "Nombre",
"placeholder": "Escribe Aquí..",
"style": {
"color": "#393E41"
}
},
"lastnameInput": {
"content": "Apellido",
"placeholder": "Escribe Aquí..",
"style": {
"color": "#393E41"
}
},
"hidePoweredBy": false,
"saveButton": {
"content": "Pagar",
"style": {
"color": "#F6F7EB",
"backgroundColor": "#7BCCE5"
}
},
"upperTag": {
"title": {
"content": "Upper Tag"
},
"description": {
"content": "Aquí puedes agregar un descuento superior"
}
},
"lowerTag": {
"title": {
"content": "Lower Tag"
},
"description": {
"content": "Aquí puedes agregar un descuento inferior"
},
"style": {
"color": "#F6F7EB",
"backgroundColor": "#FFFF00"
}
},
"cardHolderInput": {
"content": "Nombre en la tarjeta"
},
"cardNumberInput": {
"content": "Número de tarjeta"
},
"installmentsInput": {
"content": "Cuotas"
},
"legalMessageText": "Al hacer clic en comprar, aceptar las",
"showOrderTotal": true,
"termsAndConditions": {
"showForGuest": true,
"showForAuth": true,
"hideCompanyDisclaimer": false
}
}
Definición de cada una de las propiedades
Propiedad | Tipo de Objeto | Descripción |
---|---|---|
logoUrl | String | URL del logotipo que se mostrará en el formulario. |
title | string | Título del formulario. |
header | Objeto | Objeto que define el contenido y el estilo del encabezado del formulario. |
--content | String | Contenido del encabezado. |
--style | Objeto | Objeto que define el estilo del encabezado, como el color del texto. |
upperTag | Objeto que define una etiqueta superior opcional en el formulario. | |
-title | Objeto | Objeto que define el título de la etiqueta superior. |
--content | String | Contenido del título de la etiqueta superior. |
-description | Objeto | Objeto que define la descripción de la etiqueta superior. |
--content | String | Contenido de la descripción de la etiqueta superior. |
cardNumberInput | Objeto que define el campo para ingresar el número en la tarjeta. | |
--content | String | Etiqueta del campo de nombre en la tarjeta. |
cardHolderInput | Objeto que define el campo para ingresar el nombre de tarjeta. | |
--content | String | Etiqueta del campo de número de tarjeta. |
installmentsInput | Objeto que define el campo para seleccionar el número de cuotas. | |
--content | String | Etiqueta del campo de cuotas. |
lowerTag | Objeto que define una etiqueta inferior opcional en el formulario. | |
-title | Objeto | Objeto que define el título de la etiqueta inferior. |
--content | String | Contenido del título de la etiqueta inferior. |
-description | Objeto | Objeto que define la descripción de la etiqueta inferior. |
--content | String | Contenido de la descripción de la etiqueta inferior. |
--style | Objeto | Objeto que define el estilo de la etiqueta inferior, como el color del texto y el color de fondo. |
legalMessageText | String | Texto legal que se mostrará junto al botón de pagar. |
showOrderTotal | Boolean | Booleano que indica si se debe mostrar el total del pedido en el formulario. |
termsAndConditions | Objeto | Objeto que define la configuración de los términos y condiciones. |
--showForGuest | Boolean | Booleano que indica si se deben mostrar los términos y condiciones para los usuarios invitados. |
--showForAuth | Boolean | Booleano que indica si se deben mostrar los términos y condiciones para los usuarios autenticados. |
hideCompanyDisclaimer | Boolean | Booleano que indica si se debe ocultar el descargo de responsabilidad de la empresa en los términos y condiciones |
Implementación
- Configuración Única: Puedes enviar el JSON de estilos personalizados (CSSCustomFile) como parte de la configuración inicial del Vault a través de la API de ConfigurationsV2. Esto aplicará los mismos estilos para todo los enlaces de pago que levantes.
- Configuración Dinámica: También puedes crear múltiples JSON de estilos personalizados y pasarlos como query params al momento de levantar el payment link para cada transacción. Esto te brinda la flexibilidad de aplicar diferentes estilos a diferentes transacciones según sea necesario.
curl --location --request POST '{{base_url}}/merchants/{{merchant_id}}/checkout/configurations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IlZOUDlOVGM2SWdxVDhhYVRqYlFnOTRPa2wzZHgtLWZfQjdNdXdTNmYzdmMiLCJ0eXAiOiJKV1QifQ.eyJlbWFpbCI6ImRldmVsb3BlcnNAZ2V0ZHVuYS5jb20iLCJleHAiOjE3MTQyNTc2NjcsImlhdCI6MTcxMzk5ODQ2NywibWVyY2hhbnRfaWQiOm51bGwsIm5ldHdvcmtfaWQiOm51bGwsInJvbGUiOiJzdXBlcmFkbWluIiwic3RvcmVfY29kZSI6bnVsbCwic3ViIjoiMSJ9.ClSQrcThoo6eKQqmbwQgzFduAZkUfhu1kynqMV-eMQZHH0BbCOpu3FQfzyIOkgSOO13LQc9d5C-sV7sriUu7PgDbRedWlnuyAgM0E057tjOXXbpmv1zK-yWz17xpoGaFJMA4lKynxG1PSeTtGek6SBwE0pd8oFehe_-dkK7yh8n5rL2keCoiaURuZnCcQGEb5vfGs84yosvez4J-Nm0kh19_tr7RithSd421EWSSXamsv7QZQB59FXiXLHM4AAPZSxvuc8gt3Mgj4HJe624RRVCcHBZQK7Cgti91JyZ10s95JoGr93vn4T_yxO-8s0wbQVkzYJbO7Q6ay79cuBDsbIKRAkgpZG-jB42-_0Nde6sDAawYFTYdcbMFuDJiK1VbkLXCF6NwS4ASG0L8VCnxWnfmTfiGvl-ZziRhF7FCGNEgwVbiBPuzfZd6sAJlOe_dY5t14IGlm2QzWa-niZxz0M0N3Q3_XeVVhP39hihg2cLUB5sqJj5_EGthI84-CKmU_7e0VRcbJhAKtg8GgpHcppWcV6dy3uj8ABuB_t55PUM_Bd9wbmvYBtesvakLAF9R0zmIRpAn5gfdPIL5Zt6gGheo1Ptn2FmD2UxnVXveg-J0jBRqNGSMCv_OOuHxxBDdL92N6bZqHT6WzLYnxte_ZHEwMrCjvVyEd2kORXPEBI0' \
--header 'Cookie: AWSALB=096u+D212v/57f6ijBB544CvL7oTM8O2rowoCEJ6gS9tXplw/h0/xAOQoY3ZL59jDbvWLN3xSWvfPXd11eqvgQzlAgiQNF7z+URIWNCev3ht2AgTr0S2hKQohmAJ; AWSALBCORS=096u+D212v/57f6ijBB544CvL7oTM8O2rowoCEJ6gS9tXplw/h0/xAOQoY3ZL59jDbvWLN3xSWvfPXd11eqvgQzlAgiQNF7z+URIWNCev3ht2AgTr0S2hKQohmAJ; AWSALB=zKTuhqTmSeuix1M/1pTj94W+dih3P6/vy6u6fBNJEp5norx03QQBWFlZ03Qki8Ni9CiqLXiAuJui4scrCW8MxGQzP8nKfPs9tino8DwWM6SQmxiomLaftNGERg/R; AWSALBCORS=zKTuhqTmSeuix1M/1pTj94W+dih3P6/vy6u6fBNJEp5norx03QQBWFlZ03Qki8Ni9CiqLXiAuJui4scrCW8MxGQzP8nKfPs9tino8DwWM6SQmxiomLaftNGERg/R; AWSALB=uKe+jxTFaHUQinMshpBZFQjfw6M5br+WR7m/aYUYW4/q0EgQyWOXF8FTaBjkTk6w4a1rK5k3K1j0kA1P194XJXg+JrZcP3l54cfzBfzjE24/lqbBmk/JOz7MCHPo; AWSALBCORS=uKe+jxTFaHUQinMshpBZFQjfw6M5br+WR7m/aYUYW4/q0EgQyWOXF8FTaBjkTk6w4a1rK5k3K1j0kA1P194XJXg+JrZcP3l54cfzBfzjE24/lqbBmk/JOz7MCHPo; AWSALB=b5IFrxTGYo8NDVZhW3MgBZojz6G7XWQ1gfTFxB0X4kEtcViPMqzBkiaEy/OSSieHTL33YGRRqFxMf7rb2DAzNg/fWLYHaS5tCLaFT6Az3Y2HAJiF04oCveba/K+M; AWSALBCORS=b5IFrxTGYo8NDVZhW3MgBZojz6G7XWQ1gfTFxB0X4kEtcViPMqzBkiaEy/OSSieHTL33YGRRqFxMf7rb2DAzNg/fWLYHaS5tCLaFT6Az3Y2HAJiF04oCveba/K+M' \
--data '{
"elements_config": {
"user_authentication_flow": false,
"init_with_guest_user": true,
"theme_config": [
{
"id": "{theme_config_id}",
"name": "theme1",
"config": "{\n \"title\": \"¡Dale vida a tu compra!🤩\",\n \"header\": {\n \"content\": \"Introduce los detalles de tu tarjeta aquí.\"\n },\n \"hidePoweredBy\": true,\n \"saveButton\": {\n \"content\": \"Pagar\",\n \"style\": {\n \"backgroundColor\": \"#866DE9\",\n \"color\": \"#ffffff\",\n \"padding\": \"10px 20px\",\n \"borderRadius\": \"25px\",\n \"cursor\": \"pointer\"\n }\n },\n \"termsAndConditions\": {\n \"showForGuest\": true,\n \"showForAuth\": false,\n \"hideCompanyDisclaimer\": true\n },\n \"showOrderTotal\": true\n}\n"
}
]
}
}'
curl --location --request POST '{{base_url}}/merchants/{{merchant_id}}/checkout/configurations' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IlZOUDlOVGM2SWdxVDhhYVRqYlFnOTRPa2wzZHgtLWZfQjdNdXdTNmYzdmMiLCJ0eXAiOiJKV1QifQ.eyJlbWFpbCI6ImRldmVsb3BlcnNAZ2V0ZHVuYS5jb20iLCJleHAiOjE3MTQyNTc2NjcsImlhdCI6MTcxMzk5ODQ2NywibWVyY2hhbnRfaWQiOm51bGwsIm5ldHdvcmtfaWQiOm51bGwsInJvbGUiOiJzdXBlcmFkbWluIiwic3RvcmVfY29kZSI6bnVsbCwic3ViIjoiMSJ9.ClSQrcThoo6eKQqmbwQgzFduAZkUfhu1kynqMV-eMQZHH0BbCOpu3FQfzyIOkgSOO13LQc9d5C-sV7sriUu7PgDbRedWlnuyAgM0E057tjOXXbpmv1zK-yWz17xpoGaFJMA4lKynxG1PSeTtGek6SBwE0pd8oFehe_-dkK7yh8n5rL2keCoiaURuZnCcQGEb5vfGs84yosvez4J-Nm0kh19_tr7RithSd421EWSSXamsv7QZQB59FXiXLHM4AAPZSxvuc8gt3Mgj4HJe624RRVCcHBZQK7Cgti91JyZ10s95JoGr93vn4T_yxO-8s0wbQVkzYJbO7Q6ay79cuBDsbIKRAkgpZG-jB42-_0Nde6sDAawYFTYdcbMFuDJiK1VbkLXCF6NwS4ASG0L8VCnxWnfmTfiGvl-ZziRhF7FCGNEgwVbiBPuzfZd6sAJlOe_dY5t14IGlm2QzWa-niZxz0M0N3Q3_XeVVhP39hihg2cLUB5sqJj5_EGthI84-CKmU_7e0VRcbJhAKtg8GgpHcppWcV6dy3uj8ABuB_t55PUM_Bd9wbmvYBtesvakLAF9R0zmIRpAn5gfdPIL5Zt6gGheo1Ptn2FmD2UxnVXveg-J0jBRqNGSMCv_OOuHxxBDdL92N6bZqHT6WzLYnxte_ZHEwMrCjvVyEd2kORXPEBI0' \
--header 'Cookie: AWSALB=096u+D212v/57f6ijBB544CvL7oTM8O2rowoCEJ6gS9tXplw/h0/xAOQoY3ZL59jDbvWLN3xSWvfPXd11eqvgQzlAgiQNF7z+URIWNCev3ht2AgTr0S2hKQohmAJ; AWSALBCORS=096u+D212v/57f6ijBB544CvL7oTM8O2rowoCEJ6gS9tXplw/h0/xAOQoY3ZL59jDbvWLN3xSWvfPXd11eqvgQzlAgiQNF7z+URIWNCev3ht2AgTr0S2hKQohmAJ; AWSALB=zKTuhqTmSeuix1M/1pTj94W+dih3P6/vy6u6fBNJEp5norx03QQBWFlZ03Qki8Ni9CiqLXiAuJui4scrCW8MxGQzP8nKfPs9tino8DwWM6SQmxiomLaftNGERg/R; AWSALBCORS=zKTuhqTmSeuix1M/1pTj94W+dih3P6/vy6u6fBNJEp5norx03QQBWFlZ03Qki8Ni9CiqLXiAuJui4scrCW8MxGQzP8nKfPs9tino8DwWM6SQmxiomLaftNGERg/R; AWSALB=uKe+jxTFaHUQinMshpBZFQjfw6M5br+WR7m/aYUYW4/q0EgQyWOXF8FTaBjkTk6w4a1rK5k3K1j0kA1P194XJXg+JrZcP3l54cfzBfzjE24/lqbBmk/JOz7MCHPo; AWSALBCORS=uKe+jxTFaHUQinMshpBZFQjfw6M5br+WR7m/aYUYW4/q0EgQyWOXF8FTaBjkTk6w4a1rK5k3K1j0kA1P194XJXg+JrZcP3l54cfzBfzjE24/lqbBmk/JOz7MCHPo; AWSALB=b5IFrxTGYo8NDVZhW3MgBZojz6G7XWQ1gfTFxB0X4kEtcViPMqzBkiaEy/OSSieHTL33YGRRqFxMf7rb2DAzNg/fWLYHaS5tCLaFT6Az3Y2HAJiF04oCveba/K+M; AWSALBCORS=b5IFrxTGYo8NDVZhW3MgBZojz6G7XWQ1gfTFxB0X4kEtcViPMqzBkiaEy/OSSieHTL33YGRRqFxMf7rb2DAzNg/fWLYHaS5tCLaFT6Az3Y2HAJiF04oCveba/K+M' \
--data '{
"elements_config": {
"user_authentication_flow": false,
"init_with_guest_user": true,
"theme_config": [
{
"id": "{theme_config_uuid_1}",
"name": "theme1",
"config": "{\n \"title\": \"¡Dale vida a tu compra!🤩\",\n \"header\": {\n \"content\": \"Introduce los detalles de tu tarjeta aquí.\"\n },\n \"hidePoweredBy\": true,\n \"saveButton\": {\n \"content\": \"Pagar\",\n \"style\": {\n \"backgroundColor\": \"#866DE9\",\n \"color\": \"#ffffff\",\n \"padding\": \"10px 20px\",\n \"borderRadius\": \"25px\",\n \"cursor\": \"pointer\"\n }\n },\n \"termsAndConditions\": {\n \"showForGuest\": true,\n \"showForAuth\": false,\n \"hideCompanyDisclaimer\": true\n },\n \"showOrderTotal\": true\n}\n"
},
{
"id": "{theme_config_uuid_2}",
"name": "theme1",
"config": "{\n \"title\": \"¡Dale vida a tu compra!👩🎤\",\n \"header\": {\n \"content\": \"Introduce los detalles de tu tarjeta aquí.\"\n },\n \"hidePoweredBy\": true,\n \"saveButton\": {\n \"content\": \"Pagar\",\n \"style\": {\n \"backgroundColor\": \"#866DE9\",\n \"color\": \"#ffffff\",\n \"padding\": \"10px 20px\",\n \"borderRadius\": \"25px\",\n \"cursor\": \"pointer\"\n }\n },\n \"termsAndConditions\": {\n \"showForGuest\": true,\n \"showForAuth\": false,\n \"hideCompanyDisclaimer\": true\n },\n \"showOrderTotal\": true\n}\n"
}
]
}
}'
- Integra tu UUID personalizado a un determinado Vault: Una vez que envías el archivo del css personalizado, el equipo de DEUNA te enviará un identificador. Con este podrás implementar por medio de query params tu css personalizado.
Ejemplo URL: Aquí como luciría tu URL con el customFile añadido:
https://elements.sandbox.deuna.io/click_to_pay?publicApiKey=${apiKey}&firstName=${encodeURIComponent(firstname)}&lastName=${encodeURIComponent(lastname)}&email=${encodeURIComponent(email)}&cssFile=UUID_FROM_DEUNA
https://elements.sandbox.deuna.io/vault?publicApiKey=${apiKey}&firstName=${encodeURIComponent(firstname)}&lastName=${encodeURIComponent(lastname)}&email=${encodeURIComponent(email)}&cssFile=UUID_FROM_DEUNA
Descripción de atributos
Atributo | Tipo | Descripción |
---|---|---|
cssFile | String | UUID generado por DEUNA. Esto identifica el archivo CSSCustomFile |
Ejemplo estructura JSON para CSSCustomFile
{
"logoUrl": "https://assets-global.website-files.com/62e806ed6cc7b20ca6dc2b93/64c2aee779502b3676e1024a_Logo%20DEUNA.png",
"title": "Pago con tarjeta crédito o débito",
"header": {
"content": "Ingresa los datos de tu tarjeta",
"style": {
"color": "#333333"
}
},
"header2": {
"content": "Detalles de Pago",
"style": {
"color": "#393E41"
}
},
"nameInput": {
"content": "Nombre",
"placeholder": "Escribe Aquí..",
"style": {
"color": "#393E41"
}
},
"lastnameInput": {
"content": "Apellido",
"placeholder": "Escribe Aquí..",
"style": {
"color": "#393E41"
}
},
"hidePoweredBy": false,
"saveButton": {
"content": "Pagar",
"style": {
"color": "#F6F7EB",
"backgroundColor": "#7BCCE5"
}
},
"upperTag": {
"title": {
"content": "Upper Tag"
},
"description": {
"content": "Aquí puedes agregar un descuento superior"
}
},
"lowerTag": {
"title": {
"content": "Lower Tag"
},
"description": {
"content": "Aquí puedes agregar un descuento inferior"
},
"style": {
"color": "#F6F7EB",
"backgroundColor": "#FFFF00"
}
},
"cardHolderInput": {
"content": "Nombre en la tarjeta"
},
"cardNumberInput": {
"content": "Número de tarjeta"
},
"installmentsInput": {
"content": "Cuotas"
},
"legalMessageText": "Al hacer clic en comprar, aceptar las",
"showOrderTotal": true,
"termsAndConditions": {
"showForGuest": true,
"showForAuth": true,
"hideCompanyDisclaimer": false
}
}
Creación por API
Para facilitar la creación mediante la API, te proporcionamos los endpoints junto con la documentación de referencia que puedes consultar para llevar a cabo el proceso (crear, actualizar, obtener y eliminar temas)
Cambio dinámico del CSSCustomFile
Algunos comercios requieren poder cambiar el custom CSS dependiendo del bin, franquicia, etc. de la tarjeta que ingrese el usuario. Para esto, widget emite un postMessage event con la información de la tarjeta y puede recibir de regreso un postMessage para que el widget actualize los estilos enviados por medio de este postMessage. Una ejemplo a continuación:
// Recibir el evento de la información de la tarjeta
window.addEventListener('message', (event) => {
let firstParsedData;
if (typeof event.data === 'string') {
firstParsedData = JSON.parse(event.data);
} else {
firstParsedData = event.data;
}
// La información de la tarjeta viene en el "parsedData" en el campo "metadata"
/*
metadata: {
cardBin: number,
cardBran: string
}
*/
const parsedData = JSON.parse(firstParsedData);
// Este evento se dispara cuando el usuario escribe los primeros 6 dígitos de su tarjeta
if (
parsedData &&
parsedData.type === "onBinDetected"
) {
iframeRef.current?.contentWindow?.postMessage(
JSON.stringify({
type: "setCustomCSS",
data: getCustomCSS(parsedData)
}),
'*'
);
}
});
const cardBrands = {
Mastercard: '#E94F37',
Visa: '#04264E'
};
// Ejemplo de función helper de getCustomCSS
export const getCustomCSS = (parsedData: any) => ({
header: {
content: 'Datos del Tarjetahabiente',
style: {
color: '#393E41'
}
},
header2: {
content: 'Detalles del Pago',
style: {
color: '#393E41'
}
},
nameInput: {
content: 'Nombre',
placeholder: 'Escribe aquí..',
style: {
color: '#393E41'
}
},
lastnameInput: {
content: 'Apellido',
placeholder: 'Escribe aquí..',
style: {
color: '#393E41'
}
},
upperTag: {
title: {
content: 'Tienes 10% de descuento'
},
description: {
content: `Debido a que tu tarjeta es ${parsedData.data?.metadata?.cardBrand}, tienes descuento`
},
style: {
color: '#F6F7EB',
backgroundColor: `${(cardBrands as any)[parsedData.data?.metadata?.cardBrand]}`
}
},
hidePoweredBy: true,
saveButton: {
content: 'Confirmar',
style: {
color: '#F6F7EB',
backgroundColor: '#393E41'
}
},
logoUrl:'https://upload.wikimedia.org/wikipedia/commons/4/44/Cin%C3%A9polis.svg'
});
Ejemplo de una Customización por CSSCustomFile
Puedes ver en este apartado cómo este CSSCustomFile va a modificar la apariencia de nuestro Vault. Fíjate en las propiedades descritas en este archivo JSON:
{
"title": "¡Dale vida a tu compra!🤩",
"header": {
"content": "Introduce los detalles de tu tarjeta aquí."
},
"hidePoweredBy": true,
"saveButton": {
"content": "Pagar",
"styles": {
"backgroundColor": "#8A2BE2",
"color": "#ffffff",
"padding": "10px 20px",
"borderRadius": "25px",
}
},
"termsAndConditions": {
"showForGuest": true,
"showForAuth": false,
"hideCompanyDisclaimer": true
},
"showOrderTotal": true
}
Updated about 13 hours ago