Maîtriser l'Intégration des Systèmes de Paiement Web
Maîtriser l'Intégration des Systèmes de Paiement Web

Sécurité des Paiements Web et Conformité PCI DSS

Bienvenue dans cette leçon dédiée à un aspect crucial de toute application web e-commerce : la sécurité des paiements et la conformité PCI DSS. Dans le contexte de notre cours "Maîtriser l'Intégration des Systèmes de Paiement Web", comprendre et implémenter des mesures de sécurité robustes n'est pas seulement une bonne pratique, c'est une obligation légale et éthique pour protéger les données sensibles de vos clients et la réputation de votre entreprise.

Introduction : L'Impératif de la Sécurité des Paiements

À l'ère numérique, les paiements en ligne sont omniprésents. Chaque jour, des millions de transactions transitent sur le web, transportant des informations hautement sensibles comme les numéros de carte bancaire, les noms des titulaires et les codes de sécurité. Cette richesse de données attire malheureusement des acteurs malveillants, rendant les systèmes de paiement des cibles privilégiées pour les cyberattaques.

La sécurité des paiements web n'est pas un luxe, mais une nécessité absolue. Une seule faille peut entraîner des conséquences dévastatrices : pertes financières pour l'entreprise et les clients, atteinte irréparable à la réputation, sanctions réglementaires sévères et poursuites judiciaires.

Dans cette leçon, nous allons explorer en profondeur les fondations de la sécurité des paiements, comprendre le cadre réglementaire PCI DSS, et examiner les stratégies techniques essentielles pour construire et maintenir des systèmes de paiement sécurisés et conformes.

Les Fondamentaux de la Sécurité des Paiements Web

Avant de plonger dans les détails techniques et réglementaires, il est crucial de saisir les menaces courantes et les principes de sécurité qui sous-tendent la protection des données de paiement.

Les Menaces Courantes contre les Systèmes de Paiement

Les attaquants utilisent une multitude de techniques pour cibler les données de paiement. Voici quelques-unes des menaces les plus répandues :

  • Attaques par injection (SQL Injection, XSS) : Ces attaques visent à injecter du code malveillant dans les entrées utilisateur pour manipuler la base de données (SQL Injection) ou exécuter des scripts côté client (Cross-Site Scripting - XSS) pour voler des informations ou détourner des sessions.
  • Attaques Man-in-the-Middle (MitM) : Un attaquant intercepte la communication entre le client et le serveur pour lire ou modifier les données de paiement en transit. C'est pourquoi l'utilisation de HTTPS est impérative.
  • Vol de données de carte (Card Skimming / Data Breaches) : Des bases de données entières sont compromises, exposant des millions de numéros de carte. Cela peut se produire via des vulnérabilités logicielles, des mots de passe faibles, ou des attaques ciblées sur l'infrastructure.
  • Phishing et Pharming : Techniques d'ingénierie sociale visant à tromper les utilisateurs pour qu'ils révèlent leurs informations de paiement sur de faux sites web ou via de faux e-mails.
  • Attaques par force brute et credential stuffing : Essais répétés de combinaisons de noms d'utilisateur et de mots de passe pour accéder à des comptes, souvent en utilisant des identifiants volés lors d'autres fuites de données.
  • Malware et Ransomware : Logiciels malveillants installés sur les systèmes pour voler des données, chiffrer des fichiers ou perturber les opérations.

Principes de Sécurité Essentiels

Pour contrer ces menaces, la sécurité des paiements s'appuie sur plusieurs principes fondamentaux :

  • Minimisation des Données : Ne collectez et ne stockez que les données strictement nécessaires pour la transaction et le service client. Moins vous avez de données, moins il y a de risque en cas de fuite.
  • Chiffrement et Tokenisation : Les données sensibles (numéros de carte) doivent toujours être chiffrées au repos et en transit. La tokenisation, qui remplace les données sensibles par un "token" non-sensible, est une technique encore plus efficace pour réduire le périmètre PCI DSS.
  • Sécurité par Couches (Defense in Depth) : Ne vous fiez pas à une seule mesure de sécurité. Implémentez plusieurs couches de défense (pare-feux, IDS/IPS, authentification forte, segmentation réseau, etc.) de manière à ce que la compromission d'une couche ne mène pas à un échec complet.
  • Surveillance Continue : Les systèmes de paiement doivent être surveillés en permanence pour détecter les activités suspectes, les tentatives d'intrusion et les anomalies.
  • Mises à jour et Gestion des Vulnérabilités : Maintenez tous les logiciels, systèmes d'exploitation et dépendances à jour. Effectuez régulièrement des analyses de vulnérabilité et des tests d'intrusion.
  • Responsabilité Partagée : La sécurité des paiements est la responsabilité de toutes les parties impliquées (marchand, passerelle de paiement, banques, fournisseurs de services).

PCI DSS : Le Cadre Réglementaire

Le Payment Card Industry Data Security Standard (PCI DSS) est la norme de sécurité des données de l'industrie des cartes de paiement. C'est le pilier central de la conformité pour toute entité qui traite, stocke ou transmet des données de cartes de paiement.

Qu'est-ce que PCI DSS ?

PCI DSS est un ensemble d'exigences de sécurité élaborées par les principales marques de cartes de paiement (Visa, MasterCard, American Express, Discover, JCB) pour assurer la sécurité des transactions par carte. Il ne s'agit pas d'une loi, mais d'une exigence contractuelle qui s'applique à toutes les organisations traitant des données de cartes de paiement.

L'objectif principal du PCI DSS est de protéger les données des titulaires de carte contre le vol et la fraude. La non-conformité peut entraîner de lourdes amendes, des pénalités, la suspension des privilèges de traitement des cartes et une perte de confiance des clients.

Les 12 Exigences PCI DSS (en bref)

La norme PCI DSS est structurée autour de 12 exigences principales, réparties en 6 objectifs :

  1. Construire et maintenir un réseau et des systèmes sécurisés :
    • Exigence 1 : Installer et maintenir une configuration de pare-feu pour protéger les données des titulaires de carte.
    • Exigence 2 : Ne pas utiliser les valeurs par défaut fournies par les fournisseurs pour les mots de passe système et autres paramètres de sécurité.
  2. Protéger les données des titulaires de carte :
    • Exigence 3 : Protéger les données stockées des titulaires de carte.
    • Exigence 4 : Chiffrer la transmission des données des titulaires de carte sur les réseaux publics ouverts.
  3. Maintenir un programme de gestion des vulnérabilités :
    • Exigence 5 : Protéger tous les systèmes contre les logiciels malveillants et mettre régulièrement à jour les logiciels ou programmes antivirus.
    • Exigence 6 : Développer et maintenir des systèmes et applications sécurisés.
  4. Implémenter des mesures de contrôle d'accès strictes :
    • Exigence 7 : Restreindre l'accès aux données des titulaires de carte en fonction du besoin de connaître.
    • Exigence 8 : Attribuer un identifiant unique à chaque personne ayant accès à l'ordinateur.
    • Exigence 9 : Restreindre l'accès physique aux données des titulaires de carte.
  5. Surveiller et tester régulièrement les réseaux :
    • Exigence 10 : Suivre et surveiller tous les accès aux ressources du réseau et aux données des titulaires de carte.
    • Exigence 11 : Tester régulièrement les systèmes et les processus de sécurité.
  6. Maintenir une politique de sécurité des informations :
    • Exigence 12 : Maintenir une politique qui traite de la sécurité de l'information pour tout le personnel.

Qui est concerné par PCI DSS ?

Toute entité qui stocke, traite ou transmet des données de titulaire de carte est concernée par PCI DSS. Cela inclut :

  • Les marchands (vendeurs en ligne, magasins physiques).
  • Les fournisseurs de services (passerelles de paiement, hébergeurs, fournisseurs de services cloud).
  • Les processeurs de paiement.
  • Les banques acquéreuses et émettrices.

Niveaux de Marchand et Conformité

Le niveau de conformité PCI DSS requis pour un marchand dépend généralement du volume de transactions par carte qu'il traite chaque année :

  • Niveau 1 : Plus de 6 millions de transactions annuelles (marchands directs) ou tout marchand ayant subi une violation de données. Nécessite un audit annuel par un Qualified Security Assessor (QSA).
  • Niveau 2 : De 1 à 6 millions de transactions annuelles. Nécessite un Self-Assessment Questionnaire (SAQ) annuel et une analyse trimestrielle du réseau par un Approved Scanning Vendor (ASV).
  • Niveau 3 : De 20 000 à 1 million de transactions annuelles. Nécessite un SAQ annuel et une analyse ASV trimestrielle.
  • Niveau 4 : Moins de 20 000 transactions annuelles. Nécessite un SAQ annuel et une analyse ASV trimestrielle.

La complexité du processus de conformité peut être considérablement réduite en déléguant la gestion des données sensibles à des fournisseurs de services conformes PCI DSS.

Stratégies et Implémentations Techniques pour la Sécurité

L'intégration sécurisée d'un système de paiement web nécessite une approche proactive et des choix techniques éclairés.

Utilisation de Passerelles de Paiement Sécurisées (Payment Gateways)

Le moyen le plus efficace de réduire votre périmètre PCI DSS est d'utiliser une passerelle de paiement certifiée PCI DSS. Ces services prennent en charge la gestion des données sensibles de la carte, réduisant ainsi la charge de conformité sur votre propre infrastructure.

  • Intégration via redirection : L'utilisateur est redirigé vers une page sécurisée hébergée par la passerelle de paiement pour saisir ses informations de carte. Votre serveur ne voit jamais ces données.
  • Intégration via iFrames ou Hosted Fields : La passerelle injecte des champs de saisie sécurisés (souvent dans des <iframe> ou des <div> contrôlés par son SDK JavaScript) directement dans votre page. Les données saisies sont envoyées directement à la passerelle, contournant votre serveur. C'est une méthode courante et recommandée.
  • Intégration API (Direct Post) : Votre serveur reçoit les données brutes de la carte et les transmet ensuite à la passerelle via une API sécurisée. Cette méthode vous rend entièrement responsable de la conformité PCI DSS de niveau le plus élevé, et est à éviter si possible.

Tokenisation et Chiffrement

Ces deux techniques sont cruciales pour protéger les données de carte.

  • Chiffrement (Encryption) : Processus de transformation des informations dans un format illisible (texte chiffré) pour quiconque ne possède pas la clé de déchiffrement. Il est utilisé pour les données au repos (dans une base de données sécurisée) et en transit (via HTTPS/TLS).
  • Tokenisation (Tokenization) : Méthode qui remplace les données sensibles (ex: numéro de carte) par un identifiant unique non sensible (un "token"). Ce token peut être stocké et utilisé pour des transactions ultérieures sans exposer les données réelles de la carte. Si un token est volé, il n'a aucune valeur en dehors du système du processeur de paiement. La tokenisation est fortement recommandée car elle retire les données de carte de votre environnement, réduisant ainsi considérablement votre périmètre PCI DSS.

Hébergement et Infrastructure Sécurisée

Même si vous utilisez une passerelle de paiement, votre propre environnement d'hébergement doit être sécurisé :

  • HTTPS/TLS : Toutes les communications entre votre site web et les navigateurs des utilisateurs, ainsi qu'entre votre serveur et la passerelle de paiement, doivent utiliser TLS 1.2 ou supérieur.
  • Pare-feux (Firewalls) : Mettez en place des pare-feux pour filtrer le trafic et bloquer les accès non autorisés.
  • Segmentation réseau : Isolez les systèmes qui traitent des données sensibles sur un segment réseau séparé.
  • Détection et prévention d'intrusion (IDS/IPS) : Surveillez le trafic réseau pour détecter et bloquer les activités malveillantes.
  • Gestion des accès : Limitez l'accès physique et logique aux systèmes critiques. Utilisez le principe du moindre privilège.

Gestion des Vulnérabilités

  • Mises à jour logicielles régulières : Maintenez à jour votre système d'exploitation, vos serveurs web, vos bases de données, vos frameworks et toutes les bibliothèques tierces.
  • Scans de vulnérabilité : Effectuez des scans réguliers (internes et externes) pour identifier les faiblesses.
  • Tests d'intrusion (Penetration Testing) : Faites auditer votre système par des experts externes pour simuler des attaques réelles.

Authentification Forte

  • Authentification Multi-Facteurs (MFA) : Exigez la MFA pour tout accès administratif à vos systèmes de paiement, serveurs ou bases de données.
  • Politiques de mots de passe robustes : Forcez des mots de passe complexes et leur renouvellement régulier.

Prévention des Fraudes

  • 3D Secure (Verified by Visa, Mastercard ID Check) : Ce protocole ajoute une étape d'authentification pour le titulaire de la carte lors d'un achat en ligne, réduisant ainsi la responsabilité du marchand en cas de fraude.
  • AVS (Address Verification System) et CVV (Card Verification Value) : Ces vérifications permettent de confirmer que la personne effectuant l'achat est bien le titulaire légitime de la carte.

Intégration Sécurisée : Exemples Pratiques

Examinons deux exemples conceptuels d'intégration pour illustrer comment les principes de sécurité sont mis en œuvre.

Exemple 1 : Intégration côté client avec des champs hébergés (Hosted Fields)

Cette méthode est très prisée car elle minimise la manipulation directe des données de carte par votre serveur, réduisant ainsi votre périmètre PCI DSS. Le SDK JavaScript de la passerelle de paiement injecte des champs de saisie sécurisés directement dans votre formulaire.

<!-- index.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Paiement Sécurisé</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .container { max-width: 600px; margin: 50px auto; padding: 20px; border: 1px solid #ccc; border-radius: 8px; }
        .form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
        .form-group input, .form-group div { width: 100%; padding: 10px; margin-bottom: 15px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; }
        button { background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
        button:hover { background-color: #45a049; }
        #payment-errors { color: red; margin-top: 10px; }
    </style>
    <!-- Inclure le SDK JavaScript de votre passerelle de paiement (ex: Stripe.js) -->
    <!-- Ceci est un exemple, remplacez par le script réel de votre passerelle -->
    <script src="https://js.stripe.com/v3/"></script> 
</head>
<body>
    <div class="container">
        <h2>Paiement de votre commande</h2>
        <form id="payment-form" action="/process-payment" method="POST">
            <div class="form-group">
                <label for="cardholder-name">Nom sur la carte:</label>
                <input type="text" id="cardholder-name" name="cardholder_name" required>
            </div>
            
            <!-- Ces divs seront remplies par les éléments sécurisés du SDK de la passerelle -->
            <div class="form-group">
                <label for="card-number-element">Numéro de carte:</label>
                <div id="card-number-element">
                    <!-- Les champs du numéro de carte seront injectés ici par le SDK -->
                </div>
            </div>
            
            <div class="form-group">
                <label for="card-expiry-element">Date d'expiration (MM/AA):</label>
                <div id="card-expiry-element">
                    <!-- Les champs d'expiration seront injectés ici -->
                </div>
            </div>
            
            <div class="form-group">
                <label for="card-cvv-element">CVV:</label>
                <div id="card-cvv-element">
                    <!-- Le champ CVV sera injecté ici -->
                </div>
            </div>
            
            <div id="payment-errors" role="alert"></div>
            
            <button type="submit">Payer 99.99 €</button>
            
            <!-- Champ caché pour stocker le token généré par la passerelle -->
            <input type="hidden" id="payment-token" name="payment_token">
        </form>
    </div>

    <script>
        // Ceci est un exemple conceptuel basé sur Stripe.js.
        // Chaque passerelle a son propre SDK avec des méthodes et objets spécifiques.
        
        document.addEventListener('DOMContentLoaded', function() {
            const stripe = Stripe('pk_test_VOTRE_CLE_PUBLIQUE'); // Remplacez par votre clé publique réelle
            const elements = stripe.elements();
            const form = document.getElementById('payment-form');
            const errorElement = document.getElementById('payment-errors');
            const paymentTokenInput = document.getElementById('payment-token');

            // Création des éléments sécurisés (Hosted Fields) pour chaque champ de carte
            const cardNumber = elements.create('cardNumber');
            cardNumber.mount('#card-number-element');

            const cardExpiry = elements.create('cardExpiry');
            cardExpiry.mount('#card-expiry-element');

            const cardCvc = elements.create('cardCvc');
            cardCvc.mount('#card-cvv-element');

            // Écoute des changements pour afficher les erreurs de validation en temps réel
            cardNumber.on('change', function(event) {
                if (event.error) {
                    errorElement.textContent = event.error.message;
                } else {
                    errorElement.textContent = '';
                }
            });

            form.addEventListener('submit', async function(event) {
                event.preventDefault(); // Empêche la soumission par défaut du formulaire

                // Création d'un token à partir des données des éléments sécurisés
                const { token, error } = await stripe.createToken(cardNumber, {
                    name: document.getElementById('cardholder-name').value
                });

                if (error) {
                    // Afficher les erreurs à l'utilisateur
                    errorElement.textContent = error.message;
                } else {
                    // Le token a été créé avec succès. Il est sûr de l'envoyer à votre serveur.
                    paymentTokenInput.value = token.id;
                    // Soumettre le formulaire avec le token (le numéro de carte réel n'est jamais sur votre serveur)
                    form.submit(); 
                }
            });
        });
    </script>
</body>
</html>

Explication du code : Le code HTML crée un formulaire de paiement. Au lieu d'avoir des input standards pour le numéro de carte, l'expiration et le CVV, nous utilisons des div vides (#card-number-element, etc.). Le SDK JavaScript de la passerelle de paiement (ici simulé avec Stripe.js) est chargé et initialise des "éléments" sécurisés qui injectent leurs propres champs de saisie dans ces div. Lorsque l'utilisateur soumet le formulaire, le JavaScript intercepte l'événement, utilise la passerelle de paiement pour transformer les données de carte en un token, puis place ce token dans un champ caché du formulaire avant de soumettre le formulaire à votre serveur. Votre serveur ne reçoit jamais les informations brutes de la carte, seulement le token non sensible.

Exemple 2 : Traitement côté serveur du token reçu

Une fois que votre serveur reçoit le token (et uniquement le token, pas les données de carte), il peut l'utiliser pour finaliser la transaction avec la passerelle de paiement via son API.

<?php
// process-payment.php (Exemple simplifié pour un serveur PHP)

// Vérifiez la méthode de requête (POST est attendue)
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405); // Méthode non autorisée
    echo "Méthode de requête non supportée.";
    exit();
}

// Récupérez le token de paiement et d'autres informations du formulaire
$paymentToken = $_POST['payment_token'] ?? null;
$cardholderName = $_POST['cardholder_name'] ?? 'Client Anonyme';
$amount = 9999; // Montant en centimes (ex: 99.99 EUR)
$currency = 'eur';

// **IMPORTANT** : Récupérez votre clé secrète depuis un endroit SÉCURISÉ (variables d'environnement, secrets manager)
// NE JAMAIS coder en dur les clés secrètes dans votre code source et NE JAMAIS les exposer côté client.
$secretKey = getenv('STRIPE_SECRET_KEY'); // Exemple pour Stripe

if (!$secretKey) {
    error_log("Erreur de configuration: la clé secrète de paiement est manquante.");
    http_response_code(500);
    echo "Une erreur interne est survenue. Veuillez réessayer plus tard.";
    exit();
}

if (!$paymentToken) {
    // Le token est absent, cela indique un problème côté client ou une tentative d'accès direct
    error_log("Tentative de paiement sans token valide.");
    http_response_code(400); // Mauvaise requête
    echo "Les informations de paiement sont incomplètes.";
    exit();
}

// Incluez l'autoloader du SDK de votre passerelle (si vous utilisez Composer)
// require_once 'vendor/autoload.php';

// Initialisez le SDK de la passerelle de paiement avec votre clé secrète
// Ceci est un exemple pour Stripe
try {
    \Stripe\Stripe::setApiKey($secretKey);

    // Créez une charge (transaction) en utilisant le token
    // La passerelle se charge de communiquer avec la banque
    $charge = \Stripe\Charge::create([
        'amount' => $amount, 
        'currency' => $currency,
        'source' => $paymentToken, // C'est ici que nous utilisons le token !
        'description' => 'Achat en ligne par ' . $cardholderName,
        'metadata' => [
            'order_id' => 'ORD-' . uniqid(), // Un ID de commande unique
            'customer_name' => $cardholderName
        ]
    ]);

    // Vérifiez le statut de la charge
    if ($charge->status === 'succeeded') {
        // Le paiement est réussi !
        // Enregistrez la transaction dans votre base de données, mettez à jour le statut de la commande, etc.
        // var_dump($charge); // Pour débogage

        // Redirigez l'utilisateur vers une page de confirmation
        header('Location: /confirmation.php?status=success&transaction_id=' . $charge->id);
        exit();
    } else {
        // Le paiement n'a pas réussi pour une raison inconnue (rare avec 'succeeded' mais possible avec d'autres statuts)
        error_log("Paiement non réussi pour le token " . $paymentToken . ": " . json_encode($charge));
        header('Location: /confirmation.php?status=failed&message=' . urlencode('Le paiement n\'a pas pu être traité.'));
        exit();
    }

} catch (\Stripe\Exception\CardException $e) {
    // Erreur liée à la carte (carte refusée, fonds insuffisants, etc.)
    $body = $e->getJsonBody();
    $err = $body['error'];
    error_log("Erreur de carte Stripe: " . $err['message'] . " (Code: " . $err['code'] . ")");
    header('Location: /confirmation.php?status=failed&message=' . urlencode($err['message']));
    exit();
} catch (\Stripe\Exception\RateLimitException $e) {
    // Trop de requêtes à l'API
    error_log("Erreur de limite de débit Stripe: " . $e->getMessage());
    header('Location: /confirmation.php?status=failed&message=' . urlencode('Service de paiement temporairement indisponible.'));
    exit();
} catch (\Exception $e) {
    // Autres erreurs générales
    error_log("Erreur générale de traitement de paiement: " . $e->getMessage());
    header('Location: /confirmation.php?status=failed&message=' . urlencode('Une erreur inattendue est survenue.'));
    exit();
}
?>

Explication du code : Ce script PHP reçoit le payment_token (qui n'est pas le numéro de carte) et d'autres informations non sensibles du formulaire soumis par le client. Il utilise ensuite ce token avec la clé secrète de l'API de la passerelle de paiement (gardée secrète sur le serveur) pour créer une "charge" (une transaction). Le rôle de votre serveur est alors de :

  1. Valider que le token et les autres données nécessaires sont présents.
  2. Appeler l'API de la passerelle de paiement avec le token et le montant de la transaction.
  3. Gérer la réponse de la passerelle (succès, échec, erreur spécifique).
  4. Mettre à jour le statut de la commande dans votre base de données.
  5. Rediriger l'utilisateur vers une page de confirmation ou d'erreur.

C'est un flux beaucoup plus sécurisé, car votre serveur n'entre jamais en contact direct avec les informations de carte bancaire, ce qui simplifie grandement votre conformité PCI DSS.

Gestion des Incidents et Audit

La sécurité des paiements est un processus continu.

  • Plan de Réponse aux Incidents : Établissez et testez régulièrement un plan détaillé sur la manière de réagir en cas de violation de données ou d'incident de sécurité.
  • Journalisation et Audit : Collectez des journaux d'événements détaillés sur toutes les activités du système, les accès et les transactions. Auditez ces journaux régulièrement pour détecter les anomalies.
  • Formation du Personnel : Sensibilisez et formez régulièrement votre personnel aux meilleures pratiques de sécurité et aux politiques PCI DSS.

Conclusion

La sécurité des paiements web et la conformité PCI DSS sont des piliers fondamentaux de toute opération e-commerce réussie. Négliger ces aspects, c'est mettre en péril l'avenir de votre entreprise et la confiance de vos clients.

En tant que développeurs et intégrateurs, vous avez un rôle crucial à jouer. Adoptez une approche de sécurité dès la conception (Security by Design), privilégiez l'utilisation de passerelles de paiement conformes, exploitez la tokenisation et le chiffrement, et assurez une gestion rigoureuse des vulnérabilités. Rappelez-vous que la conformité PCI DSS n'est pas une tâche ponctuelle, mais un engagement continu qui nécessite une vigilance et une adaptation constantes aux menaces émergentes.

En maîtrisant ces concepts et en appliquant ces bonnes pratiques, vous contribuerez non seulement à la pérennité de vos projets mais aussi à un écosystème de paiement en ligne plus sûr pour tous.