Aller au contenu principal
Sur cette page

Personnalisez vos solutions DEUNA à l'aide de CustomStyle.

DEUNA vous permet d'adapter visuellement la caisse pour l'aligner sur l'identité visuelle de votre marque. Ce guide décrit comment configurer le fichier JSON qui contrôle les styles des widgets, notamment les couleurs, la typographie, les bordures, le texte et les vues spécifiques.

Comment fonctionne la personnalisation#

  1. Définir les éléments à personnaliser : Identifiez les vues de paiement ou les composants que vous souhaitez modifier (boutons, champs, récapitulatif de la commande, messages d'erreur, etc.).
  2. Configurez le fichier JSON : Incluez les valeurs de style que vous souhaitez appliquer. Vous pouvez modifier les couleurs, la typographie, le rayon de la bordure, le remplissage, etc.
  3. Appliquez la configuration :
    • Pour les styles de widget de base, contactez votre TPM pour la mise en œuvre.
    • Pour les styles spécifiques à une commande, vous pouvez inclure le fichier de style dans la tokenisation de chaque commande.

Portée générale#

Vous pouvez personnaliser les aspects suivants :

  • Couleurs de caisse
  • Typographie
  • Texte, hauteur et rayon des entrées et des boutons
  • Couleurs de bordure de saisie par état
  • Activer la réinitialisation du texte dans les entrées
  • Activer le validateur iconographique dans les entrées
  • Emplacement et taille du logo
  • Conditions générales
  • Éléments visuels dans des vues spécifiques (tels que OTP, cartes, page de remerciement, données de facturation, etc.)

Styles globaux#

Personnalisez les styles globaux de votre boutique.

Couleur

Vous pouvez définir des couleurs pour :

  • Contexte (primaire/secondaire)
  • Texte principal
  • Bouton de paiement (couleur, survol, texte, actif)
JSON
{
  "theme": {
    "colors": {
      "primaryTextColor": "#323237",
      "backgroundSecondary": "#FFFFFF",
      "backgroundPrimary": "#FFFFFF",
      "buttonPrimaryFill": "#17171A",
      "buttonPrimaryHover": "#69696E",
      "buttonPrimaryText": "#FFFFFF",
      "buttonPrimaryActive": "#5F529E"
    }
  }
}

Typographie

Vous pouvez choisir parmi les polices compatibles suivantes :

  • Heeb

  • Postérieur

  • Lato

  • Montserrat

  • Mukta

  • Nunito

  • Ouvrir Sans

  • Sables mouvants

  • Robot

  • Chemin de fer

  • San Francisco

  • Ubuntu

JSON
{
  "theme": {
    "typography": {
      "primaryFontFamily": "Lato"
    }
  }
}

Exemple :

Rayon de saisie et de bouton

Vous pouvez définir le border-radius en pixels pour les entrées et les boutons :

JSON
{
  "theme": {
    "inputs": {
      "borderRadius": "50px"
    },
    "buttons": {
      "borderRadius": "20px"
    }
  }
}

Hauteur de saisie et de bouton

Vous pouvez définir une hauteur personnalisée pour les entrées et les boutons. Par défaut, la hauteur est de 40px.

Pour une meilleure expérience utilisateur, utilisez une hauteur minimale de 30 px et maximale de 60 px.

JSON
{
  "theme": {
    "buttons": {
      "borderRadius": "20px",
      "heigh": "50px"
    },
    "inputs": {
      "borderRadius": "90px",
      "height": "50px"
    }
  }
}

Couleurs de bordure de saisie par état

Vous pouvez sélectionner une couleur de bordure spécifique pour les entrées en fonction de leur état.

ÉtatDéfinitionCouleur par défaut
DisabledL'entrée n'est pas activée pour l'utilisateur, celui-ci ne peut donc pas écrire dans l'entrée.# B4B4B7
EnabledL'entrée est activée, mais n'a pas encore été ciblée ou l'utilisateur n'a rien écrit.#D9D9DB
FocusL'utilisateur est en train de taper ou se concentre sur la saisie.# 404046
FilledLa saisie a été complétée avec des données valides.#8E8E92
ErrorL'entrée contient des erreurs de validation ou est incomplète lorsqu'elle est requise.#E11900
JavaScript
 theme: {
    colors: {
    inputBorder: '#D9D9DB', // Default state (enabled)
    inputBorderError: '#F1998E', // Error state
    inputEnhancerFill: '#1AE1D7', // Active state (focus)
    inputBorderPositive: '#66D19E', // Success state
    },
  },

Activer la réinitialisation du texte dans les entrées

Vous pouvez placer un bouton de réinitialisation dans tous les champs de texte. Par défaut, ce paramètre est désactivé. Il agit comme un raccourci pour effacer tout le texte du champ sans revenir en arrière.

JavaScript
 theme: {
    inputs: {
      inputMode: 'clearable' // 'validated' | 'clearable' | 'none'
    },
  },

Activer le validateur iconographique dans les saisies de texte

Vous pouvez activer un validateur iconographique dans les saisies de texte. Par défaut, ce paramètre est désactivé. Il se compose d'une icône à l'intérieur de l'entrée, alignée à droite, selon l'état :

  • Pourvu : Vérifiez ✅
  • Erreur : Exclamation ❗️
JavaScript
 theme: {
    inputs: {
      inputMode: 'validated' // 'validated' | 'clearable' | 'none'
    },
  }

Fait référence aux configurations disponibles pour le logo

  • Changer de logo
  • Changer l'emplacement du logo : centre ou gauche
  • Changer la taille du logo

Par défaut: logo 100px situé à gauche du widget

JavaScript
{
  "HeaderPattern": {
    "overrides": {
      "Logo": {
        "props": {
          "url": "https://host.com/custom_logo.png",
          "position": "center",
          "style": {
            "min-width": "150px"
          }
        }
      }
    }
  }
}

Conditions générales

Avec cette configuration, configurez les textes légaux et les liens qui apparaissent en bas d'un écran ou d'un formulaire du type « En continuant, vous acceptez nos CGV… ».

JavaScript
{
  "TermsConditionsPattern": {
    // Hide terms for non authenticated users //  Muestra términos para usuarios invitados (no autenticados)
    "showForGuest": true,
    
    // Hide terms for authenticated users // Oculta términos para usuarios autenticados (ya los aceptaron al registrarse)
    "showForAuth": false,
    
    // Legal message in HTML // Mensaje legal personalizado con HTML. Sobrescribe el texto por defecto traducido.
    // If used, the inline links replace the <A> patterns // Si usas esto, los links inline reemplazan los componentes <A> del patrón
    "legalMessage": "Al continuar, aceptás nuestros <a href='https://tusitio.com/terminos-y-condiciones'>Términos y Condiciones</a> y nuestra <a href='https://tusitio.com/politica-de-privacidad'>Política de Privacidad</a>.",
    
    // Connector texts between Privacy Polcy and Terms & Conditions // Texto conector entre "Política de Privacidad" y "Términos y Condiciones"
    // Overides the default translation (t('andThe')) // Sobrescribe la traducción por defecto (t('andThe'))
    "connectorText": "y",
    
    // Hides the  [Brand] sufix // Oculta el sufijo "de [Marca]" al final del disclaimer
    "hideCompanyDisclaimer": true,
    
    // Terms PDF/page URL. Fallbac URLs are preset by default by country of merchant // URL del PDF/página de términos. Fallback: URLs por defecto según país del merchant
    "termsAndConditionsUrl": "http://static.cinepolis.com/resources/pe/documents/terminos-y-condiciones.pdf",
    
    // Privacy policy PDF/page URL. Fallbac URLs are preset by default by country of merchant // URL del PDF/página de política de privacidad. Fallback: URLs por defecto según país
    "privacyPolicyUrl": "http://static.cinepolis.com/resources/pe/documents/politica-de-privacidad.pdf",
    
    // Changes the behaviour: shows explicit acceptance checkout // CAMBIA COMPLETAMENTE EL COMPORTAMIENTO: muestra checkbox de aceptación explícita
    // Only supported by Click to Pay // Solo soportado para Click to Pay. Estado guardado en UserContext.hasAcceptedTermsAndConditions
    // For Click to Pay // Para Click to Pay, si es false, NO VAMOS A MOSTRAR NINGÚN TIPO DE TYC.
    "requiresAcceptance": true,
    
    // Click to pay terms & conditions  URL // Url para los terminos y condiciones propias de click to pay.
  },
  
  "LegalInfoPattern": {
    // Hides the "Powered by dLocal" legal footer // Oculta el logo "Powered by dLocal" del footer legal
    "hidePoweredBy": true
  },
  
  "PoweredByPattern": {
    // Customized image URL //  URL de imagen personalizada para reemplazar el logo de dLocal
    "url": "https://1000logos.net/wp-content/uploads/2021/05/Coca-Cola-logo.png",
    
    // Inline CSS styles for custom image // Estilos CSS inline para la imagen personalizada
    "imageStyle": {
      "width": "50px",
      "height": "200px"  
    },
  }
}

Personnalisations par section#

Personnalisez les sections de votre solution.

Affichage du code de vérification

Cette vue apparaît lorsqu'il est demandé à l'utilisateur de valider son identité via un code de mot de passe à usage unique envoyé par e-mail. Cela fait partie du flux d'authentification.

La vue de vérification est facultative.

Personnaliser :

  • En-tête
  • Boutons de changement de chaîne (SMS/e-mail)
  • Option "Continuer en tant qu'invité"
JSON
{
  "OtpPage": {
    "translations": {
      "es": {
        "views": {
          "otp_view": {
            "title": "🇪🇸 Ingresa el código de verificación",
            "description": "🇪🇸 Para ver tus tarjetas guardadas ingresa el código enviado a ",
            "continue_as_guest": "🇪🇸 Continuar sin ingresar el código",
            "code_expiration_message": "🇪🇸 El código expira en: ",
            "error_timeout": "🇪🇸 Tiempo agotado. Solicita un nuevo código.",
            "resend_code": "🇪🇸 Reenviar código",
            "send_code_by_email": "🇪🇸 Enviar código por correo",
            "send_code_by_phone": "🇪🇸 Enviar código por SMS",
            "new_code_alert": "🇪🇸 ¡Recibiste un nuevo código!"
          }
        }
      },
      "en": { ... },
      "pt": { ... }
    }
  }
}

Vue du paiement par carte

Correspond au formulaire principal où l'utilisateur saisit les détails de sa carte pour finaliser l'achat.

Personnaliser :

  • Titres et sous-titres de sections : modifier ou masquer les textes
  • Étiquettes de champ (telles que le numéro de carte, le nom et les versements)
  • Texte du bouton de paiement
  • Avis d'information UpperTag / LowerTag (non disponible sur le lien de paiement).
  • Messages juridiques et liens vers les termes et conditions
JSON
{
  "PaymentMethodsPattern": {
    "translations": {
      "es": {
        "inputs": {
          "card": {
            "securityCode": {
              "label": "CVV"
            },
            "installment": {
              "label": "Cuotas",
              "pay_by": "Paga en",
              "first_pay": "Primer pago",
              "without_interest": "Sin interés ",
              "without_installments": "Sin cuotas",
              "loading": "Validando cuotas..."
            },
            "cardHolder": {
              "label": "Nombre como aparece en la tarjeta",
              "placeholder": "Ej. Juan Zapata"
            },
            "cardNumber": {
              "label": "Número de tarjeta",
              "placeholder": "0000 0000 0000 0000"
            },
            "expirationDate": {
              "label": "Fecha expiración",
              "placeholder": "MM / YY"
            }
          }
        },
        "paymentMethods": {
          "info": {
            "card": {
              "title": "tarjeta crédito o débito",
              "subtitle": "Por favor, ingresa los datos de tu tarjeta"
            }
          }
        }
      },
      "en": {...},
      "pt": {...}
    },
    "props": {
      "hideTitleForCreditCard": true
    }
  }
}

Vue des cartes enregistrées (utilisateurs authentifiés)

S'affiche lorsqu'un utilisateur authentifié a déjà stocké des cartes et peut choisir entre elles pour finaliser son achat.

Vous pouvez personnaliser :

  • Textes des boutons
  • Messages ou avertissements d'expiration
  • Confirmation de suppression
JSON
{
  "UserCardPattern": {
    "translations": {
      "es": {
        "addNewCard": {
          "info": "Add a card"
        },
        "moreOptions": {
          "payWith": "Selected card"
        },
        "paymentMethods": {
          "expiredCard": "Expired card",
          "confirmDeleteMethodTitle": "Delete this card",
          "confirmDeleteMethod": "Please note that once deleted, you won't be able to restore it."
        }
      },
      "en": {...},
      "pt": {...}
    }
  }
}

Page de remerciement

Écran de confirmation d'achat qui apparaît à la fin du processus s'il n'est pas redirigé vers un autre site.

Vous pouvez personnaliser :

  • Merci titre
  • Statuts des commandes (succeeded, pending, denied)
  • Texte du bouton : "Enregistrer le reçu", "Retour au magasin"
JSON
{
  "ThankYouView": {
    "translations": {
      "es": {
        "thankYouPage": {
          "title": "🇪🇸 Gracias por tu compra",
          "status": {
            "succeeded": "🇪🇸 ¡Gracias por tu compra!",
            "pending": "🇪🇸 Procesando...",
            "denied": "🇪🇸 Pago rechazado"
          },
          "downloadVoucher": "🇪🇸 Descargar comprobante",
          "backToCommerce": "🇪🇸 Volver a la tienda"
        }
      },
      "en": {...},
      "pt": {...}
    },
    "overrides": {
      "Actions": {
        "props": {
          "hideDownloadAction": false,
          "hideBackToCommerceAction": false
        }
      }
    }
  }
}

Exemple :

Page des bons d'achat

Écran d'instructions pour les paiements avec des méthodes alternatives (par exemple, paiements en espèces ou virements).

Vous pouvez personnaliser :

  • Titre, sous-titre, description

  • Messages de référence et délai de paiement

  • Texte du bouton

  • Afficher/masquer la marque DEUNA

Configurez votre JSON avec l'un des identifiants de processeur de paiement suivants :

  • SPEI
  • OXXO_PAY
  • OXXO_REFERENCE
  • PAYU_EFECTY
  • BAZ_REFERENCE
  • SPEI_OPENPAY
  • SPEI_OPM
  • SAFETY_PAY
  • STP_CODI
  • PIX

Remplacer [PROCESSOR_NAME] dans votre configuration JSON avec l'une des valeurs répertoriées ci-dessus.

Exemple OXXO :

JSON
{
  "VoucherPage": {
    "[PROCESSOR_NAME]": {
      "es": {
        "overrides": {
          "Header": {
            "props": {
              "title": "🇪🇸 Comprobante de Pago PIX",
              "subtitle": "🇪🇸 Tu transacción fue procesada exitosamente"
            }
          },
          "Footer": {
            "props": {
              "downloadReference": "🇪🇸 Descargar Comprobante",
              "showPoweredByDeuna": false
            }
          }
        }
      },
      "en": { ... },
      "pt": { ... }
    },
    "[PROCESSOR_NAME]": {
      "es": { ... },
      "en": { ... },
      "pt": { ... }
    }
  }
}

Affichage des informations sur l'utilisateur

Formulaire initial où les données de base de l'acheteur sont demandées, telles que le nom, l'e-mail, le téléphone et la pièce d'identité. Cette vue est facultative et disponible uniquement pour le lien de paiement et le paiement complet.

Permet de personnaliser les champs liés à :

  • Titre de la section
  • Étiquettes pour tous les champs
JSON
{
  "UserInfoPattern": {
    "translations": {
      "es": {
    		"title": "Title custom style",
        "inputs": {
          "email": { "label": "email style" },
          "firstName": { "label": "label style" },
          "lastName": { "label": "lastName style" },
          "phone": { "label": "phone style" },
          "identityDocument": {
            "label": {
              "CO": "Cédula / Doc de identidad",
              "CL": "RUT/DNI",
              "EC": "Cédula / Doc de identidad",
              "MX": "Número de RFC",
              "BR": "Registro Geral",
              "AR": "DNI / Doc de identidad",
              "UY": "Cédula / Doc de identidad"
            }
          }
        }
      },
      "en": {...},
      "pt": {...}
    }
  }
}

Vue des données de facturation

Formulaire pour saisir les données de facturation, si le commerçant ou la réglementation l'exige. Il s'agit d'une vue facultative disponible dans le lien de paiement, le widget de paiement et le widget de paiement complet.

Permet de personnaliser :

  • Titre de la section
  • Étiquettes pour tous les champs
JSON
"BillingPatternX": {
    "translations": {
      "es": {
        "addBillingData": {
          "error": "Debes ingresara los datos de facturación para continuar. ✅",
          "optionalTag": "No obligatorio",
          "title": "Añadir información"
        },
        "billingSummary": {
          "dni": "Documento",
          "update": "Modificar"
        },
        "billingView": {
          "cancel": "Anula",
          "save": "Guardar cambios",
          "title": "Introduce tu información de facturación"
        },
        "billingWithSameData": {
          "title": "Usar los mismos datos de facturación"
        },
        "inputs": {
          "companyBilling": {
            "activity": {
              "label": "Giro/Actividad"
            },
            "address": {
              "label": "Domicilio fiscal"
            },
            "authorizingFirstName": {
              "label": "Nombre del responsable"
            },
            "authorizingIdentityDocument": {
              "label": "Identificación del responsable"
            },
            "authorizingLastName": {
              "label": "Apellido del responsable"
            },
            "city": {
              "label": "Localidad"
            },
            "email": {
              "label": "Correo electrónico"
            },
            "identityDocument": {
              "label": "Registro fiscal"
            },
            "label": "Entidad jurídica",
            "name": {
              "label": "Razón social"
            },
            "phone": {
              "label": "Teléfono de contacto"
            }
          },
          "errors": {
            "identityDocument": "Número de CPF o CNPJ incorrecto",
            "inputRequired": "Campo obligatorio",
            "invalidEmail": "Email inválido",
            "invalidZipcode": "Código postal incorrecto",
            "phoneInvalid": "Teléfono no válido"
          },
          "personBilling": {
            "additionalDescription": {
              "label": "Zona/Barrio"
            },
            "address1": {
              "label": "Domicilio"
            },
            "address2": {
              "label": "Piso / Depto / Torre"
            },
            "city": {
              "label1": "Localidad",
              "label2": "Municipio",
              "label3": "Localidad/Municipio"
            },
            "country": {
              "label": "Nación",
              "placeholder": "Selecciona tu nación"
            },
            "email": {
              "label": "Email"
            },
            "firstName": {
              "label": "Nombre propia"
            },
            "identityDocument": {
              "errorMessage": "Debe ser un documento de identidad válido.",
              "invalidByCountry": {
                "AR": "DNI o identificación incorrecta",
                "BR": "CPF o CNPJ inválido",
                "CL": "RUT o DNI incorrecto",
                "CO": "Cédula no válida",
                "EC": "Cédula no válida",
                "MX": "RFC incorrecto",
                "UY": "Cédula no válida"
              },
              "label": "Identificacións"
            },
            "label": "Persona física",
            "lastName": {
              "label": "Apellido familiar"
            },
            "phone": {
              "label": "Número telefónico"
            },
            "stateName": {
              "label1": "Provincia",
              "label2": "Departamento",
              "placeholder": "Elige una provincia",
              "placeholder2": "Elige un departamento"
            },
            "zipCode": {
              "lbel": "Código postal"
            }
          }
        },
        "title": "Dirección de la tarjeta"
      }

Page de paiement fractionné

Permet au client de répartir la valeur totale de la commande entre deux paniers. Idéale pour les achats de grande valeur ou si l'utilisateur souhaite utiliser plusieurs modes de paiement, il s'agit d'une fonctionnalité dédiée à Vault.

Permet de personnaliser :

  • Étiquettes d'en-tête
  • Formulaire d'étiquette de carte
  • Étiquette « Montant à payer »
  • Etiquette « Montant total à payer »
  • Texte du bouton
  • Étiquettes de facturation de la deuxième carte
  • Étiquette récapitulative
JSON
{
  "SplitPaymentPage": {
    "translations": {
      "es": {
        "stepper": {
          "backToSinglePayment": "Custom Style text",
          "label": "Custom Style text"
        },
        "common": {
          "enterCardDataLabel": "Custom Style text",
          "totalAmontLabel": "Custom Style text"
        },
        "amountToPayCard": {
          "title": "Custom Style text"
        },
        "footerButton": {
          "goToCard2": "Custom Style text",
          "goToPurchase": "Custom Style text"
        },
        "useSameBillingCheckbox": {
          "label": "Custom Style text"
        },
        "billingSection": {
          "title": "Custom Style text %{ordinal}"
        },
        "lastStep": {
          "title": "Custom Style text"
        }
      }
    }
  }
}

Exemple

IMPORTANT : Le billingSection > title la personnalisation du texte comprend le %{ordinal} variable d'interpolation. Cette variable affiche dynamiquement l'étape actuelle de la carte (par exemple, "Deuxième", "Troisième", etc.). Vous devez conserver cette variable dans le texte personnalisé pour éviter l'affichage d'étiquettes incorrectes.

Exemple :

JSON
{
  "SplitPaymentPage": {
    "translations": {
      "es": {
        "billingSection": {
          "title": "Datos Fact. %{ordinal} tarjeta"
        },
      }
    }
  }
}

Versements

Ce message apparaît lorsque vous saisissez une carte dont le BIN (numéro d'identification bancaire) n'est pas éligible aux paiements échelonnés.

Permet de personnaliser :

  • Texte de l'étiquette
  • Texte de l'info-bulle
  • Répertoriez les éléments expliquant pourquoi les versements sans intérêt ne s'appliquent pas
  • Styles d'info-bulles (couleurs, remplissage, etc.)
JSON
{
  "InstallmentsPattern": {
    "overrides": {
      "NoInstallmentsTooltip": {
        "label": "¿Por qué no puedo pagar a meses sin intereses?",
        "popoverProps": {
          "title": "¿Por qué no puedo pagar a MSI?",
          "list": [
            "Tu compra es menor a $2,500",
            "Tu tarjeta es de débito",
            "Tu banco no es participante",
            "Los productos no son aplicables a la promoción MSI"
          ],
          "listType": "unordered",
          "textColor": "red",
          "styles": {
            "padding": "16px",
            "backgroundColor": "blue"
          }
        }
      }
    }
  }
}

Exemple :



Page de redirection

Il permet au client de visualiser l'état du paiement après avoir terminé le défi d'un APM, comme celui de 3DS.

Permet de personnaliser :

  • Informations sur les messages
  • Texte d'état
  • Texte de la barre de progression
JSON
{
  "PurchaseStatusView": {
    "translations": {
      "pt": {
        "purchaseStatus": {
          "info": {
            "processed": "Processado Info PT - ☸",
            "cancelled": "Pagamento cancelado PT - ☸",
            "pending": "Pendente PT - ☸",
            "pending_3ds": "Pendente 3DS PT - ☸",
            "denied": "Negado PT - ☸"
          },
          "message": {
            "processed": "message Processado PT - ☸",
            "cancelled": "message Cancelado PT - ☸",
            "pending": "message Pendente PT - ☸",
            "pending_3ds": "message Pendente 3DS PT - ☸",
            "denied": "message Negado PT - ☸"
          },
          "redirecting": "Redirecionando PT"
        }
      }
    }
  }
}

Exemple :


Dans cette section