Introduction
Mercanet est une solution de paiement de commerce électronique multicanale sécurisée conforme à la norme PCI DSS. Elle vous permet d’accepter et de gérer des transactions de paiement en prenant en compte les règles métiers liées à votre activité (paiement à la livraison, paiement différé, paiement récurrent, paiement en plusieurs fois, …).
L’objectif du présent document est d’expliquer la mise en œuvre de la solution Mercanet CSE jusqu’au démarrage en production.
Objectif de ce document
L’objectif du présent document est d’expliquer la mise en œuvre de la solution de chiffrement côté client (CSE) jusqu’au démarrage en production.
Le chiffrement côté client est une fonctionnalité qui vous permet de chiffrer les informations de paiements sensibles (numéro de carte et code csc) et de les traiter par la passerelle de paiement Office (M2M).
Cette fonctionnalité vous permettra de réduire les contrainte PCI et ainsi n’être soumis qu’aux impacts de type SAQ A-EP (cf : https://www.pcisecuritystandards.org/pci_security/completing_self_assessment)
A qui s'adresse ce document ?
Ce document s’adresse aux commerçants qui souhaitent souscrire à l’offre Mercanet en réduisant leurs contraintes PCI DSS. Le chiffrement coté client permet d'héberger les pages chez le commerçant sans que les données cartes ne transitent en clair.
Pour avoir une vue d'ensemble de la solution Mercanet, nous vous conseillons de consulter les documents suivants
- Présentation fonctionnelle.
- Guide de configuration des fonctionnalités.
Prérequis
Une connaissance élémentaire des standards relatifs aux langages de programmation Web pratiqués aujourd’hui, tels que Java, PHP ou .Net, est nécessaire pour développer la connexion à Mercanet CSE.
Gestion de la clé secrète
Lors de votre inscription, BNP Paribas met à disposition sur Mercanet Téléchargement (voir votre guide de démarrage rapide, annexe « Télécharger la clé secrète »), une clé secrète qui permet de sécuriser les échanges entre votre site et le serveur Mercanet.
Vous êtes responsable de sa conservation et devez prendre toutes les mesures pour :
- en restreindre l'accès ;
- la sauvegarder de manière chiffrée ;
- ne jamais la copier sur un disque non sécurisé ;
- ne jamais l'envoyer (e-mail, courrier) de manière non sécurisée.
La compromission de la clé secrète (et son utilisation par un tiers malveillant) perturberait le fonctionnement normal de votre boutique, et pourrait notamment générer des transactions et des opérations de caisse injustifiées (des remboursements par exemple).
C’est la même clé secrète qui est utilisée sur les différents connecteurs Paypage, Office (M2M), In-App et Walletpage.
Gestion de la clé CSE
La fonctionnalité Mercanet Client Side Encryption requiert l’utilisation d’une clé de chiffrement. De la même manière que la clé Secrète, la clé CSE est mise à disposition sur l’extranet Mercanet Téléchargement.
Comprendre le paiement avec Client Side Encryption
Le chiffrement côté client consiste en une bibliothèque JavaScript intégrée à votre page de paiement. Elle chiffre les données sensibles avant que le formulaire Web ne soit soumis à votre serveur.
Les données chiffrées obtenues sont ensuite utilisées pour appeler les services de paiement par carte Office (M2M) pour traitement.
La fonctionnalité CSE offre les avantages suivants:
- Les clients ne sont pas obligés d'être redirigés vers une page hébergée chez Mercanet (Paypage)
- Les impacts PCI sont réduits car aucune donnée sensible ne passe en clair sur votre serveur.
1. Le formulaire permettant de saisir les informations relatives de paiement inclus la librairie Java Script CSE ainsi que la clé publique. Les données de carte sont interceptées par la librairie et chiffrées grâce à la clé.
2. Vous enregistrez les détails du paiement.
3. Vous envoyez les informations relatives au paiement vers le serveur de paiement Mercanet pour qu’il prenne en charge la transaction.
4. Le serveur Mercanet déchiffrent les données en récupérant la clé privé CSE et effectue le paiement.
5. Le serveur Mercanet envoie une réponse pour que vous puissiez afficher le résultat du paiement.
Implémenter Client Side Encryption en 4 étapes
Pour compendre comment démarrer avec Office (M2M), merci de vous reporter à la documentation dédiée.
Le mode CSE est disponible pour
les fonctions cardOrder
, cardCheckEnrolment
, addCard
lorsque le champ panType
est positionné à CSE et pour
walletOrder
, walletCheckEnrolment
lorsque le champ
cscType
est positionné à
CSE.
Inclure la librairie SDPX CSE
Pour utiliser le mode CSE, il vous faut inclure la librairie de chiffrement Mercanet dans la balise <head> de votre page de paiement.
Il y a deux façons de procéder:
- Chargement standard JavaScript
<script type="text/javascript" src="https://office-server.mercanet.bnpparibas.net/scripts/cse/latest/sdpx.encrypt.js"></script>
- Chargement avec le module AMD
La librairie de chiffrement SDPX est compatible avec AMD et peut être utilisée avec tout module AMD ou librairie telle que RequireJS.
RequireJS recommande d’inclure votre script de cette façon :
<script data-main="scripts/main" src="scripts/require.js"></script>
Cela garantit un seul point d'entrée pour votre application, car le data-main du script que vous spécifiez sera chargé de manière asynchrone.
Ensuite, dans main.js, vous pouvez utiliser la fonction require pour charger la bibliothèque de chiffrement SDPX.
<script> require(['https://office-server.mercanet.bnpparibas.net/scripts/cse/latest/sdpx.encrypt.js'], function(sdpx) { // ... }); </script>
Dans l'exemple ci-dessus, le premier paramètre de la fonction require est un tableau de modules dépendants pour votre application. Le nom du module (i.e scripts/sdpx.encrypt représente le nom du fichier JS sans l’extension).
Si vous le souhaitez, vous pouvez configurer RequireJS pour qu’il mappe le chemin par souci de commodité:
<script> requirejs.config({ baseUrl: './', paths: { 'sdpx.encrypt': 'https://office-server.mercanet.bnpparibas.net/scripts/cse/latest/sdpx.encrypt' } }); require(['sdpx.encrypt'], function(sdpx) { // ... }); </script>
Implémenter le formulaire HTML de paiement
<!DOCTYPE html>
<html lang="en">
<head>
<title>Merchant payment page</title>
</head>
<body>
<form id="payment-form">
<input type="text" id="card-number" sdpx-encrypted />
<input type="text" id="card-expiry-month" />
<input type="text" id="card-expiry-year" />
<input type="text" id="card-csc-value" sdpx-encrypted />
<input type="submit" value="Checkout"/>
</form>
</body>
</html>
Actuellement, les services de paiement par carte Office (M2M) prennent en charge le chiffrement pour le numéro de carte et le code CSC.
Lier l'évènement de validation du formulaire de paiement à la bibliothèque CSE
<script>
var paymentFormId = 'payment-form';
var merchantCseKeyValue = '00CE1A815AA0E970EB6E70...9434E9578F000308AD1E1B|010001';
var merchantCseKeyVersion = '2';
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentFormId, merchantCseKeyValue, merchantCseKeyVersion);
</script>
onSubmitEncryptForm doit être appelée après le chargement de la page.
Cela signifie que le script ci-dessus doit être inséré à la fin de la section <body> ou différé en utilisant, soit la propriété onload sur l'élément <body>, soit l’ajout d'un listener pour détecter la fin du chargement du DOM de la page (voir DOMContentLoaded et readystatechange).
document.onreadystatechange = function () {
if (document.readyState === "interactive") {
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentFormId, merchantCseKeyValue, merchantCseKeyVersion);
}
}
Tester sur l’environnement de recette client
Les étapes de test et d'intégration peuvent être réalisées à l’aide de l'environnement de recette.
L’URL de l’environnement de recette est : https://office-server-mercanet.test.sips-services.com/
Pour effectuer ce test, il faut utiliser ces identifiants :
ID du Commerçant | 201040040170001 |
Version de la clé sécrète | 1 |
Clé sécrète | rxSP61eeP_oNi5TxCD7Ngy9YcwC8MLw6OlmFGGcsY54 |
Version de la clé CSE | 3 |
Clé CSE | 00AA519EC129B375E8E30DCA7018251433907DF339439 DF0402ABADDD20F3198AB4EC152D830E48ED9B3402660 5BB614897176ECD15DF887A6A79A7392E81BEB2C3CA8D 33FB5E9F9B31DA7809EF1D4EE0B02F3DA15F39B003548 9B53030E2D73AFF4D75433E72C7B614C8852F6E1B99A8 4B50973CD3ACAC642270E636C74739D08C75F11CB9716 8FC23EEFCEACD375BED6C2EE3B826D787F80B282DEC63 EC61FFBCBEC5426E26F423A783D6585865439153E1AF7 23F132933CA7671F8D6A9E9C3AF351081D1465EA20689 2F8D7E1ABBA53373BB4D370A7E02E374E394A8FA20481 C2A121BF7F0300007B7DAD4E69CD66CD99C344D3EC6E7 359EED51D9C6326C01D|010001 |
Usage avancé
Activation de la validation des champs
La bibliothèque SDPX CSE peut être utilisée pour valider des champs côté client. Par défaut, cette fonctionnalité n'est pas activée, mais elle peut être utile car les champs chiffrés ne peuvent être validés côté serveur.
Pour activer la validation des champs côté client, un tableau contenant les définitions des champs à valider peut être ajouté à l'objet renvoyé par la fonction onSubmitEncryptForm. Une entrée du tableau est une structure JSON avec les propriétés suivantes:
Propriété | Obligatoire | Description |
---|---|---|
id | oui | Id de l’élément HTML à valider |
validator | oui | Référence du validateur par défaut ou fonction personnalisée utilisée pour valider la valeur du champ |
onSuccess | non | Fonction de rappel invoquée lorsque la valeur du champ a été validée avec succès |
onError | non | Fonction de rappel invoquée lorsque la valeur du champ n'a pas été validée avec succès |
<script>
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentForm, merchantCseKeyValue, merchantCseKeyVersion);
var fieldValidationDefs = [
{ id: 'card-number', validator: '@CardNumber', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-csc-value', validator: '@CscValue', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-expiry-month', validator: '@ExpiryMonth', onSuccess: successValidationHandler, onError: errorValidationHandler },
{ id: 'card-expiry-year', validator: '@ExpiryYear', onSuccess: successValidationHandler, onError: errorValidationHandler }
/*
// Custom validator example:
{ id: 'card-expiry', validator: customCardExpiryValidator, onSuccess: successValidationHandler, onError: errorValidationHandler }
*/
];
paymentForm.setValidations(fieldValidationDefs);
/**
* Custom validator example: check the card expiry value (format 'mm/yyyy')
*
* @param {value} the HTML input element value to validate
* @return {boolean} true if the value is valid, false otherwise
*/
function customCardExpiryValidator(val) {
// Validate the card expiry value
return /^[0-9]{2}\/[0-9]{4}$/.test(val);
}
/**
* Handle success validation
*
* @param {element} the HTML element that has been successfully validated
* @return {void}
*/
function successValidationHandler(element) {
// Do sthg if needed
}
/**
* Handle error validation
*
* @param {Error} a JSON object containing error information
* @return {void}
*/
function errorValidationHandler(error) {
// Handle error
}
</script>
Validateur de champ par défaut
Reference | Description | Code source |
---|---|---|
@CardNumber | Vérifie que le numéro de carte est compris entre 6 et 19 chiffres | return /^[0-9]{6,19}$/.test(val); |
@CscValue | Vérifie que le code csc est compris entre 3 et 4 chiffres | return /^[0-9]{3,4}$/.test(val); |
@ExpiryMonth | Vérifie que le mois est compris entre 1 et 12. | return /^[0-9]{2}$/.test(val) && (val > 0) && (val <= 12); |
@ExpiryYear | Verifie que l'année est valide | return /^[0-9]{4}$/.test(val) && (val >= (new Date()).getFullYear()); |
Rappel de la structure de l'objet JSON
Reference | Description | Exemple |
---|---|---|
message | Message d’erreur ('is invalid!') | card-number is invalid! |
validator | Nom de la référence du validateur ou de la fonction personnalisée utilisée pour la validation | @CardNumber, customCardExpiryValidator, ... |
element | Elément HTML qui est validé | HTMLElement |
cause | Objet d'erreur JavaScript décrivant l'échec de la validation | Error:* Error('Validation returns false')* Error('No validator found for element [<field-id>]') |
Gestion des erreurs
Par défaut, en cas d'incident lié à l'utilisation de la bibliothèque CSE, une erreur JavaScript est interceptée et la soumission du formulaire est annulée.
Pour être prévenu de l'erreur JavaScript, une fonction de rappel peut être fournie à l'objet renvoyé par la fonction onSubmitEncryptForm.
<script>
var paymentForm = sdpx.encrypt.onSubmitEncryptForm(paymentForm, merchantCseKeyValue, merchantCseKeyVersion);
paymentForm.setErrorHandler(errorHandler);
function errorHandler(error) {
// Display an error message to the end user and send information to your server
}
</script>